[xml] Statically compiled Libxml2 Python module


We required a libxml2 python module for a web application using a
newer version of libxml2 than the system installation
provided. Upgrading the system installation was not an option for us,
and all we needed was the python module without the rest of the
libxml2 install. The solution seems to be a static libxml2 python
module as opposed to the one normally produced which dynamically links
to libxml2.so

I couldn't find a standard way to do this and so resorted to the
following procedure. If there are any easier ways to do
this/improvements I'd be glad to hear of them! If not, then perhaps
the instructions will be of use to anyone else just needing the python
libxml2 module without the rest of the distribution.

This was performed on an i686 linux runing Red Hat.

1. Obtain the libxml2 distribution file, extract it and change to its root directory e.g.:

cd /tmp
tar -xzf libxml2-sources-2.6.23.tar.gz
cd /tmp/libxml2-2.6.23

2. Configure the package, ensuring that the --with-python switch is used:

./configure --with-python

3. Compile the package


   If all went smoothly, the files ./.libs/libxml2.a and
   ./.libs/libxml2.so should exist. The first is an archive containing
   all the static libxml2 objects and the second is the libxml2 shared

4. We don't want to install the entire package, only python, so change
   to the python directory:

cd python/

5. Compile the python module specifying CFLAG and LD_LIBRARY_PATH
   environment variables that identify our package e.g.:

CFLAGS=-I/tmp/libxml2-2.6.23/include LD_LIBRARY_PATH=/tmp/libxml2-2.6./.libs python setup.py build

   This will have built the core python module
   build/lib.linux-i686-2.4/libxml2mod.so The only problem with this
   is that it is dynamically linked. However, the process shows us the
   compiler command which we can modify to produce a static
   build. This command should be the last line output from the above
   command and be something along the lines of:

gcc -pthread -shared -I/tmp/libxml2-2.6.23/include build/temp.linux-i686-2.4/libxml2-py.o 
build/temp.linux-i686.4/libxml.o build/temp.linux-i686-2.4/types.o -lxml2 -lm -lz -o 

6. The -lxml2 switch is what dynamically links the resulting
   lxml2mod.so with libxml2 in the above command. We need to replace
   this with static objects. These are located in the libxml2.a file
   mentioned in step 3. To view the contents of this file try
   something along the lines of:

ar t ../.libs/libxml2.a

   These object files should be placed in a directory for our convenience:

mkdir libxml2_static
cd libxml2_static
ar xv ../../.libs/libxml2.a
cd ..

7. Re-run the compile command output in step 5, replacing -lxml2 with
   libxml2_static/*.o and specifying the output file (-o) to be
   libxml2mod.so instead of lxml2mod.so:

gcc -pthread -shared -I/tmp/libxml2-2.6.23/include build/temp.linux-i686-2.4/libxml2-py.o 
build/temp.linux-i686-2.4/libxml.o build/temp.linux-i686-2.4/types.o libxml2_static/*.o -lm -lz -o 

   You may have to fix some of the build/temp* paths if the compiler
   complains, but as a result you should have a statically compiled
   libxml2mod.so. You can strip this to reduce it's size:

strip build/lib.linux-i686-2.4/libxml2mod.so

   ... and ensure it has the correct permissions:

chmod a+rx build/lib.linux-i686-2.4/libxml2mod.so

8. You can now move the libxml2 module to wherever it is that you need
   it (ensuring the destination directory is one that your Python
   application searches when loading modules):

chmod a+r build/lib.linux-i686-2.4/*
cp -p build/lib.linux-i686-2.4/* /my/destination/directory

9. Phew!

Kind regards,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]