Saturday, December 29, 2012

Slaying the automake/autoconf dragon

After quite a few years of avoiding it, I decided today was the day to get a project compiling with autoconf/automake. The project is a new C++ JSON parser I've written. It consists of a shared library and a test suite that is based on cppunit. Notably, the project is based on flex (lex) and bison (yacc), which presented certain problems with automake (more on that below).

The big "ahah" moment for me was discovering "autoscan", which does the work of generating a configure.ac file automatically based on a source directory. 

Here are the steps.

First, I created a directory for all my project

$ mkdir myproject
$ cd myproject
$ mkdir src
$ mkdir test

I then copied all the source and header files for the shared library into src, and the two source files (one c++, the other a header) into test.

In addition to c++ sources, the src dir also contains a c++ bison source (with a .ypp suffix) and a flex source (with a .lpp suffix). Using ypp and lpp cause automake to generate c++ source files, which is important for my project.

Here's what the directories looked like after copying srcs:

./src/jsonapi.cpp
./src/json.ypp
./src/jsonobj.cpp
./src/lex.lpp
./src/context.cpp
./src/yyerror.cpp
./src/jsonapi.h
./src/context.h
./src/jsonparse.cpp
./src/jsonparse.h
./src/jsonobj.h
./test/jsonapitest.cpp
./test/jsonapitest.h

Next step involved using a tool to scan the above directory and generate some skeleton automake/autoconf files. While in myproject:

$ autoscan
$ mv configure.scan configure.ac

Then, I edited configure.ac, so that it looked like the following:

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.68])
AC_INIT([jsonapi], [1.0], [xxx@gmail.com])
AC_CONFIG_SRCDIR([src/jsonapi.cpp])
AC_CONFIG_HEADERS([config.h])

AM_INIT_AUTOMAKE(jsonapi, 1.0)
LT_INIT

# Checks for programs.
AC_PROG_CXX
AC_PROG_LEX
AC_PROG_YACC

# Checks for libraries.

# Checks for header files.
AC_CHECK_HEADERS([memory.h string.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL

# Checks for library functions.
AC_CHECK_FUNCS([strstr])

AC_CONFIG_FILES([Makefile src/Makefile test/Makefile])
AC_OUTPUT

Next, I typed:

$ aclocal
$ autoconf

This generates a script called configure, which will be used later.

Next, I created a Makefile.am file in the myproject directory:

AUTOMAKE_OPTIONS = foreign
SUBDIRS = src test

I also created one in src:

AM_CXXFLAGS = --pedantic -Wall -O2 -I ../src
AM_LDFLAGS =

# deal with bug with generating header file from flex.

BUILT_SOURCES = json.cpp lex.cpp json.h lex.h
CLEANFILES = lex.h
lex.h : lex.lpp
        $(LEX) --header-file=$@ -o /dev/null $<
AM_YFLAGS = -d


lib_LTLIBRARIES = libjsonparse.la
libjsonparse_la_SOURCES = json.ypp lex.lpp context.cpp context.h \
                          jsonapi.cpp jsonapi.h \
                          jsonobj.cpp jsonobj.h \
                          jsonparse.cpp jsonparse.h \
                          yyerror.cpp


and one in test:

AM_CXXFLAGS = --pedantic -Wall -O2 -I ../src
AM_LDFLAGS = -lcppunit -ljsonparse

bin_PROGRAMS = jsonapitest
jsonapitest_SOURCES = jsonapitest.cpp  jsonapitest.h

You'll notice in the src Makefile.am I had to go to extra trouble to get flex to generate a header file that is needed by other sources. This should be fixed in versions of autoconf late 2012 (my version of autoconf that came with Ubuntu 12.04 did not have the fix). The fix will allow you to specify the --header-file argument using an AM_LFLAGS macro (similar to how AM_YFLAGS is used to pass -d to bison).

The following commands were used to generate the Makefiles:

$ autoreconf -i
$ automake --add-missing
$ ./configure

Finally, I issued the following command to build and install my library, and to generate a test program:

$ sudo make install









Saturday, October 27, 2012

Creating a new git repo on a remote server

Let's say you have some source code and you want to create a new git repo on a remote server, and check it in there. Here's the simple steps to create a new repo and push the code you have written. I assume you have git installed in both places and have done the basics to properly initialize things, e.g., add git users and so on.

First, ssh onto the remote machine (for this example, call it myhost) and then:
  • cd to location you want the repo (in my case, on Mac OS X this is /Volumes/SRV-EXT2)
  • mkdir mynewrepo
  • cd mynewrepo
  • git init --bare
back on the machine where the code exists:
  • cd into source dir
  • git init
  • git add your files (I like to add them individually, "git add ," may pick up unwanted files)
  • git commit
  • git remote add origin gituser@myhost:/Volumes/SRV-EXT2/mynewrepo
  • git push origin master
 That's it.

Tuesday, October 23, 2012

C++ STL for Arduino

It may not be obvious, but Arduino is programmed in C++.

However, the core libraries do not support the Standard Template Library, which has (in my opinion) indispensable support for generic containers like vector, list, map, and so on.

Well, some kind person did a straight port of the uClibC implementation of STL, and it is available here:

https://github.com/maniacbug/StandardCplusplus

The instructions are pretty clear, but I will summarize:
  • Open up your Arduino IDE, go to preferences, and locate your sketchbook (details here: http://www.arduino.cc/en/Guide/Environment). On my Ubuntu 12.04 machine, it is /home/slogan/sketchbook. Chdir to that location and then type:
$ mkdir -p libraries
  • Download the StandardCplusplus tarball into the libraries directory you just created, and unpack it with
$ tar -zxvf file (where file is the name of the tarball)
  • Exit arduino IDE if running, then restart.
  • Go to File->Examples/StandardCplusplus and select one of the examples, and compile it.
I haven't done any testing but given it is a straight port from uClibC I'm not expecting surprises. This is a huge plus for me, because other than occasionally using Boost (most recently for regex), the STL containers are essential for my style of C++ programming.

Enjoy.



Sunday, October 21, 2012

Django-like URL handling in C++

I wrote some code tonight (and checked it into github @ https://github.com/slogan621/djangourl) that aims to provide URL handling that is similar to how Django handles URLs.  From the readme file:

djangourl
=========

Simple C++ classes that wrap boost regex, and invoke a callback on matches, 
similar to django urls.py

To use this code, simply copy djangourls.cpp and djangourls.h into your
project. 

On Linux, you will need the boost regex dev package, on debian/Ubuntu, you
can get it like this:

$ sudo apt-get install libboost-regex-dev

See the test directory for an example. The regular expressions in that
example are pulled from django docs, and explained there. See the URL
https://docs.djangoproject.com/en/dev/topics/http/urls/ for more details.
The example is roughly analogous to the following urls.py:

from django.conf.urls import patterns, url, include

urlpatterns = patterns('',
    (r'^articles/2003/$', 'news.views.special_case_2003'),
    (r'^articles/(\d{4})/$', 'news.views.year_archive'),
    (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
    (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)

with the exception that in the sample, a single callback function is being
used. Of course, you can declare as many classes/objects that you like to
act as handlers when a match comes in.
 
 


Friday, October 19, 2012

Git server on Mac OS X

Some decent looking instructions for setting up GIT server on Mac OS X:

http://blog.smitec.net/posts/setting-up-a-git-server-on-osx/

Mostly correct. Setup non-ssh for local use only, which means I can only push origin master only while inside my firewall (and that I must always supply a password for the gituser account). Cloning is done with git clone gituser@host:/path (note the missing http or git prefix on the URL).

Thursday, October 18, 2012

vimrc

I know that this may seem trivial, but I need some webby place to store the core vimrc I use, so many times I am spinning up a VM or am on some new machine where I want this.

Surprisingly, it doesn't take much of a vimrc to make me happy. This one is derived from one that was used at VMware to adhere to the coding standard.

set hidden                      " Allow sane buffer switching
set shiftwidth=4                " for coding standard
set backspace=2                 " allow backspacing over in insert mode
set textwidth=78                " always limit the width of text to 78
set expandtab                   " expand tabs to spaces
set smarttab                    " tabs -> shiftwidth
set showmatch                   " show matching brackets
set tabstop=8                   " set tabstop (coding standard)
set cinkeys-=0#                 " don't indent # comments
set history=100         " Number of lines of command line history.
set undolevels=100      " Number of undo levels.



Sunday, May 20, 2012

A couple of blogs related to GPIO on beagleboard:

http://wh1t3s.com/2009/05/14/reading-beagleboard-gpio/
http://blog.makezine.com/2009/02/03/blinking-leds-with-the-beagle-board/




Thursday, May 17, 2012

GPIO on Beagleboard xM rev C

For BB xM Rev C the expansion pin 24 (GPIO168) is reserved for the I2C SCL signal and it cannot be changed without tweaking U-Boot and kernel settings. You can export GPIO168 just fine and it appears as if you could change the state, however the pin stays high no matter what you do.

Instead one should use pin 22 for instance (GPIO157). This works fine.

So:

cd /sys/class/gpio
echo "157" > export
cd gpio157
echo "low" > direction (voltage on pin 22 should go low)
echo "high" > direction (voltage on pin 22 should go to 1.82V)

Sunday, February 12, 2012

BeagleBoard xM Ubuntu 11.04

1) Insert microSD card reader in USB.

2) Unmount, if necessary.

3) sudo sh -c 'zcat ubuntu-11.04-preinstalled-headless-armel+omap.img.gz > /dev/sdb'; sync; sync

Above image was downloadable from http://cdimage.ubuntu.com/releases/11.04/release/

Insert microsd card in beagle and power on. Run minicom in separate terminal with serial USB attached to configure.

As with angstrom, wireless card is a problem (iogear) though driver has been a part of kernel for sometime and is stable (and this wireless card has plenty of testimony that it works). Ordered belkin model which documentation for beagle says works better (some say it is only card that works). Has me wondering if it is a hardware issue with beagleboard USB. Configuring for wired net works.

During configuration, selected Ubuntu server and openssh options.

While the wireless doesn't yet work (assuming it is the chip) the following is what I would expect the file /etc/network/interfaces to look like:

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto usb0
iface usb0 inet dhcp

auto wlan0
iface wlan0 inet dhcp
wireless-mode managed
wireless-essid sydXXXX

Saturday, February 4, 2012

A couple of chumby things worth remembering

1) to remount / rw:
# mount -o remount,rw /
2) to have sshd enabled always
# touch /psp/start_sshd
3) kill the shell on the serial port:
# vi /etc/inittab and comment out the line starting with ttyAM0