Archive for the ‘bash’ Category

KiCad OS X nightly development builds are back

Wednesday, February 9th, 2011

After about eight months of not running I have fixed my nightly builds of KiCad for OS X. I have finally found the time to switch my KiCad repository over to the Bazaar and launchpad system that the KiCad developers have been using for some time now.

After a few changes here and there and updating wxWidgets to 2.9.1 I have the nightly build system back up and running. The build script I am using is given at the end of this post in Listing 4.

The KiCad compiling instructions for OS X have been updated and now work a lot better. You should be able to find the latest version over at launchpad here.

In case anyone else runs into similar problems I have repeated some of the errors and my hacks/work-arounds solutions below.

The nightly builds themselves are here as usual.

Getting it to compile again.

After following the compilation instructions referred to above, I ran into the following error. After a bit of web crawling and reading development lists I found that I needed to use the XML library built into wxWidgets rather than the system one.

The error looked like this:

Linking CXX executable eeschema.app/Contents/MacOS/eeschema
Undefined symbols:
“_XML_GetErrorCode”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_ErrorString”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_SetUnknownEncodingHandler”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_SetCharacterDataHandler”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_SetUserData”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_ParserFree”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_SetCdataSectionHandler”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_SetCommentHandler”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_Parse”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_SetElementHandler”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_ParserCreate”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_GetCurrentLineNumber”, referenced from:
_StartCdataHnd in libwx_osx_cocoau-2.9.a(monolib_xml.o)
_CommentHnd in libwx_osx_cocoau-2.9.a(monolib_xml.o)
_TextHnd in libwx_osx_cocoau-2.9.a(monolib_xml.o)
_StartElementHnd in libwx_osx_cocoau-2.9.a(monolib_xml.o)
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
“_XML_SetDefaultHandler”, referenced from:
wxXmlDocument::Load(wxInputStream&, wxString const&, int)in libwx_osx_cocoau-2.9.a(monolib_xml.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
make[2]: *** [eeschema/eeschema.app/Contents/MacOS/eeschema] Error 1
make[1]: *** [eeschema/CMakeFiles/eeschema.dir/all] Error 2
make: *** [all] Error 2

Error 1: Missing XML library

This was fixed by adding the --with-expat=builtin option when configuring wxWidgets.

This then lead me to another error to do with wxWidgets headers using anonymous enums and anonymous types. Part of this second error is shown below.

/opt/wxwidgets-svn/include/wx-2.9/wx/combo.h: In member function ‘bool wxComboPopup::IsCreated() const’:
/opt/wxwidgets-svn/include/wx-2.9/wx/combo.h:774: error: ‘‘ is/uses anonymous type
/opt/wxwidgets-svn/include/wx-2.9/wx/combo.h:774: error: trying to instantiate ‘template struct boost::polygon::is_polygon_90_set_type’
/opt/wxwidgets-svn/include/wx-2.9/wx/combo.h:774: error: ‘‘ is/uses anonymous type
/opt/wxwidgets-svn/include/wx-2.9/wx/combo.h:774: error: trying to instantiate ‘template struct boost::polygon::is_polygon_45_or_90_set_type’
/opt/wxwidgets-svn/include/wx-2.9/wx/combo.h:774: error: ‘‘ is/uses anonymous type
/opt/wxwidgets-svn/include/wx-2.9/wx/combo.h:774: error: trying to instantiate ‘template struct boost::polygon::is_any_polygon_set_type’
make[2]: *** [gerbview/CMakeFiles/gerbview.dir/class_gerber_draw_item.cpp.o] Error 1
make[1]: *** [gerbview/CMakeFiles/gerbview.dir/all] Error 2
make: *** [all] Error 2

Error 2: Anonymous enums using anonymous types being marked as errors by the compiler

Rather than figure out which flag to set on the cmake/compiler/linker mess, I went for a brute-force approach that I found here after a small amount of searching. I have expanded from the script given to the ones below to account for the particular style used in the wxWidgets header files.

for i in `grep -l ‘enum {‘ *.h | sed -e ‘s/\.h//g’` ; \
do \
perl -pi -e \
“s/enum {/’enum en_$i’ . int(rand(100)) .’ {‘/eg” $i.h; \
done

Listing 1: Small script to replace all occurances of “enum {” with “enum en_filenameXX {“

Listing 1 is the original script given which enumerates the anonymous enums with a name consisting of the filename (without the extension) and a random number from 0-99.

This next command I adapted from the first to account for the fact that the style of the wxWidgets header files meant that a lot of the enums were declared with the keyword enum alone on a line with the rest of the declaration on the following line. This finds those declarations and assigns them a name similar to the first script but with a number from 100-199 to ensure we don’t repeat names already given. It is shown below in Listing 2.

for i in `grep -l ‘^enum en_.*$’ *.h | sed -e ‘s/\.h//g’` ;\
do \
perl -pi -e \
“s/^enum$/’enum en_$i’ . int(rand(100)+100) .”/eg” $i.h;\
done

Listing 2: Small script to replace all occurrences of “enum” with “enum en_filename1XX ” where “enum” occurs by itself on a line and assuming the rest of the declaration continues on the following line.

The problem with the previous two scripts is that they use a random number to assign the unique identifier. Being random there is the possibility that this number can come up twice.
This last command (Listing 3) helps us check for duplicate names generated by the previous scripts. We then need to go in and fix the duplicates by hand.

grep ‘enum en’ *.h | sort | uniq -c | sort -n

Listing 3: Command to check for duplicate names created by previous two scripts.

A single script could be written to give unique identifiers to all the anonymous enums and ensure that the identifiers are unique. But as this was a quick enough process and solved my problems I haven’t bothered to refine it further. Perhaps next time I update wxWidgets I’ll give it another thought. I thought this was a useful enough hack to share.

Automating the builds

Listing 4 below shows my daily build script which automatically updates the code to the latest development snapshot via Bazaar. Next it will check if the version has changed and if so build and package the latest version. If this all goes well we compress the new version into an archive and upload it to the website. If the compilation does not complete according to plan then the error log and some other useful information is uploaded to the website instead. Note that all usernames and passwords have been changed to placeholders in this version. This is run every day (or night depending on your time zone) by a cron job.

#!/bin/sh
#
. /Users/nick/.bashrc

#Make a nightly build of KiCad

#update from launchpad using bazaar
cd /Temp/kicad.bzr/kicad/
bzr update

new_version=`bzr revno`
old_version=`cat /temp/install/version.txt`
if [ $new_version -gt $old_version ]
then

#build it
cd build/release

cmake ../../ -DwxWidgets_CONFIG_EXECUTABLE=”/usr/local/bin/wx-config” -DwxWidgets_ROOT_DIR=”/opt/wxwidgets-svn/include/wx-2.9/” -DCMAKE_INSTALL_PREFIX=”/temp/install” -DCMAKE_OSX_ARCHITECTURES=”ppc -arch i386 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk/ -mmacosx-version-min=10.5″ -DCMAKE_CXX_FLAGS=”-D__ASSERTMACROS__” -DCMAKE_OSX_SYSROOT=”/Developer/SDKs/MacOSX10.5.sdk”

# make clean
if make > /temp/kicad_errors-${new_version}.txt 2>> /temp/kicad_errors-${new_version}.txt && make install
then
file=kicad_osx_v${new_version}
echo $new_version > /temp/install/version.txt
mv /temp/kicad_errors-${new_version}.txt /temp/install/build_log.txt

#bundle
cd /temp/
cp -rf install ${file}
tar -czf ${file}.tgz ${file}

#upload
curl -T ${file}.tgz ftp://user:password@ftp.brokentoaster.com/
rm -rf ${file}

# cd /temp/kicad-sources/build/release/
# /Developer/usr/bin/packagemaker –doc osx-package.pmdoc –title ‘Kicad’ -o ${file}.mpkg
# curl -T ${file}.mpkg ftp://user:password@ftp.brokentoaster.com/

else

#insert some useful debug info
echo “*** GCC Version Info ***”>> /temp/kicad_errors-${new_version}.txt
gcc -v >> /temp/kicad_errors-${new_version}.txt

echo “*** wxWdgets Version Info ***”>> /temp/kicad_errors-${new_version}.txt
wx-config –list >> /temp/kicad_errors-${new_version}.txt
head /Volumes/Store/wxWidgets-2.9.1/osxbuild/config.log >> /temp/kicad_errors-${new_version}.txt

curl -T /temp/kicad_errors-${new_version}.txt ftp://user:password@ftp.brokentoaster.com/
fi

# go to sleep
if [ ! -e /Users/nick/Applications/insomnia.flag.true ]
then
open /Users/nick/Applications/SleepNow.app
fi
else
echo “KiCad is up to date : ) ”
fi

Listing 4: BASH script to update, build and upload KiCad. This is run daily via a cron job

So if you want to test the latest developer build of KiCad on OS X then look no further than here.

Battery Capacity Logger MkII

Saturday, November 14th, 2009

A minor update to my battery logger script to tidy up the format of the log file and to make a slightly nicer (maintainable) script file.

#!/bin/sh
# batterylogger.sh : Log the battery capacity to a file
#
filename=/var/log/batterycapacity.log
date=`date`
capacity=`system_profiler SPPowerDataType |grep "charge capacity"`
count=`system_profiler SPPowerDataType |grep "Cycle count"`
echo ${date} ${capacity} ${count} >> ${filename}

This gives a log file output like the following

Sat 14 Nov 2009 13:45:06 GMT Full charge capacity (mAh): 4740 Cycle count: 163

To create the log file in a sensible place like /var/log/ I did the following:

sudo touch /var/log/batterycapacity.log
sudo chmod 666 /var/log/batterycapacity.log

I’ve also switched to using periodic instead of cron as I can’t seem to get cron to work reliably. To make it work with periodic I simply place my batterylogger.sh script in the directory /etc/periodic/daily/

NOTE: I’ve had a couple of issues lately with pasting from the web into a script file and finding i get the following error:
No such file or directory´╗┐#!/bin/sh

I’ve found that this problem is due to binary characters in my text file. I think they are UTF-8 encoded characters that have slipped in from cutting and pasting. To solve this problem I use the command vim -b script. This will load up the file in binary mode so I can see what funny characters have found their way into my file. After deleting the offending character or characters the script functions as expected.