Archive for the ‘Tutorial’ Category

Serving git from an unmodified webserver

Saturday, August 30th, 2008

There’s a tutorial on BadPopcorn that is the first place I’ve actually seen all the steps a git newbie needs to follow to make a repository accessible from a regular, unmodified webserver. Thanks Ben!

Installing cerberus on bluehost

Sunday, July 6th, 2008

We were impressed by the cerberus helpdesk software that bluehost was running, and since we needed something similar for our own site (not coincidentally hosted with bluehost), we decided to take a shot at installing it. It worked out, but had some tricky bits. So here are the steps that worked for us.

We began by downloading Cerberus (the free community edition) and following their instructions for unpacking it, setting permissions, and getting started on installation.

First problem: Cerberus complains when checking server requirements that a php extension called mailparse is missing. It really wants this extension, but it isn’t available on bluehost. Are we stuck? No! We can install the plugin ourselves. We worked from a helpful write-up someone had made for an imagemagick extension. We did the following from our bluehost shell:

pecl download mailparse
tar xvzf mailparse-*.tgz
cd mailparse-*
phpize
./configure
make

This gave us a “modules” directory with a mailparse.so file, which is what we need. We moved it into our home directory on bluehost, so we had the file /home/our_user_name/modules/mailparse.so

Then we need to tell PHP where to find this extension. To do this, we opened the php.ini file that bluehost created in our web directory, and modified the following entries:

;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories ;
;;;;;;;;;;;;;;;;;;;;;;;;;

extension_dir = “/home/our_user_name/modules”

;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;

extension=”mailparse.so”

While editing this file, we also set the “upload_tmp_dir” away from the default, since cerberus didn’t like that.

At this point, we had a problem with the new information in the php.ini file not getting used. Probably it suffices to wait, but we gave php a “kick” from the bluehost control panel “Php Config” just for testing purposes. And indeed Cerberus at this point was happy with its new home and ready to start operations.

The only remaining problem was quick a nasty one. When setting up incoming mail, we could never get the mail test to pass, until finally one of us had a brainwave and replaced the “+” symbol that bluehost email usernames have with its url-encoded version “%2B”. This worked like a charm. But then when we tried the system for real, email logins were failing. So we put back the “+” and found that the real system worked with this while the test stopped working. Yuck, but no real problem. We suggest you get things working with the test first, using “%2B” instead of “+”, and then when that test is passing put back in the “+”.

Done!

silent grainy happy lizard demo posted

Wednesday, July 2nd, 2008

Our demo video for ucanvcam has caught up with the latest version. See the silent grainy happy lizard demo. The videography leaves something to be desired, but the main point is that effects can be created online with the picture mixer and downloaded as stills or animations. So put your video stream in a heart or on a wine bottle and enjoy!

ucanvcam documentation update

Wednesday, May 28th, 2008

Instructions about using the ucanvcam virtual camera on linux and windows have been updated in the user manual.

Coming soon: create pictures or animations with the picture mixer, and use them from ucanvcam.

compiling on one linux machine, running on another

Tuesday, February 19th, 2008

What stops a program compiled on one linux machine from running on another? Libraries, mostly. The libraries available on one machine may not be on the other, or may have different versions.

It is generally quite easy to get something you compile on one linux machine to run on another. Here’s how.

Suppose I’ve just compiled a program called “killerapp” on machine A, and now want it to run on machine B. But if I just copy it across, here’s what happens when I try to run it on B:

./killerapp: error while loading shared libraries: libcgicc.so.5: cannot open shared object file: No such file or directory

This means I’m using a library that isn’t on the other machine. Of course, I could try installing all the same libraries on B as there are on A. Suppose we can’t or don’t want to do that. Then our alternative is to statically link libraries with our program.

On B, run the command “ldd killerapp”. This will give something like:

linux-gate.so.1 => (0xffffe000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0xf7f77000)
libdl.so.2 => /lib/libdl.so.2 (0xf7f73000)
libgd.so.2 => /usr/lib/libgd.so.2 (0xf7f26000)
libcgicc.so.5 => not found
libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0xf7f08000)
libpng12.so.0 => /usr/lib/libpng12.so.0 (0xf7ee4000)
libz.so.1 => /usr/lib/libz.so.1 (0xf7ed3000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xf7e0b000)
libm.so.6 => /lib/tls/libm.so.6 (0xf7de8000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xf7dde000)
libc.so.6 => /lib/tls/libc.so.6 (0×45b43000)
/lib/ld-linux.so.2 (0×45b29000)
libXpm.so.4 => /usr/X11R6/lib/libXpm.so.4 (0xf7dcf000)
libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0xf7cef000)
libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0xf7c84000)
libXext.so.6 => /usr/X11R6/lib/libXext.so.6 (0xf7c76000)

The list on the left is the libraries our program is looking for, and then on the right are the local versions it finds. We’ve got a “not found” in there for a library called “libcgicc”. This is a library present on A, the machine we are compiling on, but absent on B, the machine we want to run on.

The extension “.so” means “dynamic library” - a library that doesn’t get included in your program, but instead will be hooked up to it when your program is run.

Libraries can also come with the “.a” extension, which means “static library” - a library that is inserted in your program and so gets copied along with it.

Let’s go back to our compiling machine, machine A, and see what “ldd killerapp” says there for libcgicc:

libcgicc.so.5 => /usr/lib/libcgicc.so.5 (0xb7f18000)

So on machine A, the library we want is in /usr/lib. If we do “ls /usr/lib/libcgicc*” we can see what versions of this library are available. On my machine that is:

/usr/lib/libcgicc.a
/usr/lib/libcgicc.la
/usr/lib/libcgicc.so
/usr/lib/libcgicc.so.5
/usr/lib/libcgicc.so.5.0.1

So there is a static version available, “libcgicc.a”. If there were not a “.a” version, we would need to get one - on debian/ubuntu, we could track it down by doing (as superuser):

apt-file search libcgicc.a

(If you haven’t used apt-file before, do “apt-get install apt-file” and “apt-file update” first).

Now, all we need to do is relink our program, replacing “-lcgicc” with “/usr/lib/libcgicc.a”. Now when we do “ldd killerapp” on either machine, we have no more missing libraries.

However, that doesn’t guarantee all libraries are exactly the same version. A frequent problem is libstdc++ for C++ code. If you see a message like this when trying to run your code:

./killerapp: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9′ not found (required by ./killerapp)

Then you’ve got a version mismatch. This may be fixable by statically linking the libstdc++ library. Check what version of g++ you are using with “g++ –version”, and then check for libstdc++.a in:

/usr/lib/gcc/[platform-name]/[version]

(location may be different on your computer). Once you track this file down you can link it statically as before.

We may also see later runtime problems, if our library versions are a bit out of whack. For example:

./killerapp: symbol lookup error: /home/foo/killerapp: undefined symbol: gdImageGifAnimBeginPtr

This is a missing method from the “gd” library on machine B. We can fix this by static linking of libgd.a following the same method. Note that when you switch from linking with -lgd to /usr/lib/libgd.a, you may have to manually link against libraries that gd depends on in turn (e.g. -ljpeg, -lpng12, etc).

And so on.

Note that if you plan on distributing a program widely, you need to think carefully about library dependencies, but for just moving from one machine to another this kind of step-by-step fixing is often good enough.