Compiling uWSGI from sources
Friday, June 3rd, 2011 10:33 am GMT +2

uWSGI

 

As you probably know, uWSGI is a fast application container for serving your webapps. It is often used with Django against nginx webserver. Written in pure C & having a lot of other cool features.

It seems that installation of uWSGI is pretty simple according to official docs but it isn’t.

If you want to deploy your Django app on a brand new linux box (VPS/Amazon EC2), using buildout without a lot of dependencies things become more complicated.

Here is how you can tune up your uWSGI:

wget http://projects.unbit.it/downloads/uwsgi-0.9.7.2.tar.gz
tar -xvvf  uwsgi-0.9.7.2.tar.gz
cd uwsgi-0.9.7.2

If  you’ll simply run make as this point, you’ll experience  something like this:

 *** libxml2 headers unavailable. uWSGI build is interrupted. You have to install libxml2 development package or use libexpat or disable XML 

Since uWSGI needs libxml2 for reading XML configs, which is only one of the available configuration options (command lineenvironment variablesXML.ini, yaml files and via LDAP.), we’re going to drop this dependency (I’m more comfortable with command-line style)

It’s not obvious how to drop libxml2 dependency, because there’s no configure & usual C-style make. Instead, build is fully controlled by uwsgiconfig.py script, which you can grok for a while to get a grasp on how the whole process works.

Build options are stored in buildconf/ folder:

root@devbox:~/server/thirdparty/uwsgi-0.9.7.2# ls -l buildconf/
total 64
-rw-r--r-- 1 root root  50 Apr  6 10:50 core.ini
-rw-r--r-- 1 root root 497 Apr  6 10:50 default.ini
-rw-r--r-- 1 root root  54 Apr  6 10:50 erlang.ini
-rw-r--r-- 1 root root  49 Apr  6 10:50 lua.ini
-rw-r--r-- 1 root root  40 Apr  6 10:50 luap.ini
-rw-r--r-- 1 root root 485 Apr  6 10:50 modular.ini
-rw-r--r-- 1 root root  78 Apr  6 10:50 package.ini
-rw-r--r-- 1 root root  50 Apr  6 10:50 psgi.ini
-rw-r--r-- 1 root root  60 Apr  6 10:50 pyerl.ini
-rw-r--r-- 1 root root  86 Apr  6 10:50 pylua.ini
-rw-r--r-- 1 root root 462 Apr  6 10:50 pyrb.ini
-rw-r--r-- 1 root root  69 Apr  6 10:50 rack.ini
-rw-r--r-- 1 root root 449 Apr  6 10:50 rackp.ini
-rw-r--r-- 1 root root 377 Apr  6 10:50 unbit.ini
-rw-r--r-- 1 root root 108 Apr  6 10:50 unbitstaff.ini

For our customized build we’ll create a new build config, called myproject.ini:

root@devbox:~/server/thirdparty/uwsgi-0.9.7.2/buildconf# cp default.ini myproject.ini 

He’re how internals should look like if you want to turn off libxml2 support:


[uwsgi]
xml = false
ini = true
yaml = true
snmp = true
sctp = false
spooler = true
embedded = true
udp = true
multicast = true
threading = true
sendfile = true
minterpreters = true
async = true
evdis = false
ldap = auto
pcre = auto
debug = false
unbit = false
; xml_implementation = libxml2
plugins =
bin_name = uwsgi
plugin_dir = .
embedded_plugins = python, ping, nagios, rpc, fastrouter, http, ugreen

locking = auto
event = auto
timer = auto
filemonitor = auto

[python]
paste = true
web3 = true

At this point you’re ready to type

 python uwsgiconfig.py --build myproject 

In theory this should build you a brand-new uWSGI, but only in theory. Probably, what you’ll get by doing above command will be:

using profile: buildconf/myproject.ini
*** uWSGI compiling server core ***
gcc -pthread -c utils.c -o utils.o -O2 -Wall -Werror -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -fno-strict-aliasing -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -DUWSGI_BUILD_DATE="\"03 June 2011 09:10:42\"" -DUWSGI_LOCK_USE_MUTEX -DUWSGI_EVENT_USE_EPOLL -DUWSGI_EVENT_TIMER_USE_TIMERFD -DUWSGI_EVENT_FILEMONITOR_USE_INOTIFY
gcc -pthread -c protocol.c -o protocol.o -O2 -Wall -Werror -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -fno-strict-aliasing -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -DUWSGI_BUILD_DATE="\"03 June 2011 09:10:42\"" -DUWSGI_LOCK_USE_MUTEX -DUWSGI_EVENT_USE_EPOLL -DUWSGI_EVENT_TIMER_USE_TIMERFD -DUWSGI_EVENT_FILEMONITOR_USE_INOTIFY
gcc -pthread -c socket.c -o socket.o -O2 -Wall -Werror -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -fno-strict-aliasing -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -DUWSGI_BUILD_DATE="\"03 June 2011 09:10:42\"" -DUWSGI_LOCK_USE_MUTEX -DUWSGI_EVENT_USE_EPOLL -DUWSGI_EVENT_TIMER_USE_TIMERFD -DUWSGI_EVENT_FILEMONITOR_USE_INOTIFY
gcc -pthread -c logging.c -o logging.o -O2 -Wall -Werror -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -fno-strict-aliasing -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -DUWSGI_BUILD_DATE="\"03 June 2011 09:10:42\"" -DUWSGI_LOCK_USE_MUTEX -DUWSGI_EVENT_USE_EPOLL -DUWSGI_EVENT_TIMER_USE_TIMERFD -DUWSGI_EVENT_FILEMONITOR_USE_INOTIFY
gcc -pthread -c master.c -o master.o -O2 -Wall -Werror -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -fno-strict-aliasing -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -DUWSGI_BUILD_DATE="\"03 June 2011 09:10:42\"" -DUWSGI_LOCK_USE_MUTEX -DUWSGI_EVENT_USE_EPOLL -DUWSGI_EVENT_TIMER_USE_TIMERFD -DUWSGI_EVENT_FILEMONITOR_USE_INOTIFY
cc1: warnings being treated as errors
master.c: In function ‘uwsgi_subscribe’:
master.c:74: error: implicit declaration of function ‘send_udp_message’

and your build will miserably fail

To fix that, you need to edit uwsgiconfig.py, find following line:

self.cflags = ['-O2', '-Wall', '-Werror', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64'] + os.environ.get("CFLAGS", "").split()

and remove -Werror

In case you want to do it automatically by your deployment scripts, here is a small sed snippet:

sed  -ie "s#'-Werror',##g" uwsgiconfig.py

After patching uwsgiconfig.py you’re ready to rock&roll:

  python uwsgiconfig.py --build myproject