I've just been trying to build "pycairo":http://cairographics.org/pycairo/, the Python wrappers for the Cairo graphics library on Mac OS X 10.5 Leopard. Unfortunately, the 1.4.0 tarball for pycairo doesn't work out the box. It'll compile, but when you try and use it you get the following error: >>> import cairo Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Library/Python/2.5/site-packages/cairo/__init__.py", line 1, in <module> from _cairo import * ImportError: dlopen(/Library/Python/2.5/site-packages/cairo/_cairo.so, 2): Symbol not found: _PycairoContext_FromContext Referenced from: /Library/Python/2.5/site-packages/cairo/_cairo.so Expected in: flat namespace The problem is that as part of the build process all but one symbol in the _cairo.so file are made private using nmedit. To stop the nmedit stage from working I changed the cairo/Makefile.in file, making like 207 look like this: <pre>_cairo_la_LDFLAGS = -module -avoid-version</pre> Essentially removing the "-export-symbols-regex init_cairo" that's in the file originally. Then the symbols are still active and things should work. Now everything should be okay to use the cairo library under Python. I assume my solution isn't correct, but at least gets me working again. I'm unfamiliar with nmedit and the symbol list generation, so I thought I'd file it for someone else to take from here. Please do get in touch if you need more information.
You can make the change you suggest by editing Makefile.am (instead of Makefile.in) before configure is run. You say "The problem is that as part of the build process all but one symbol in the _cairo.so file are made private using nmedit." I don't agree that this is the problem, in fact, from my understanding of Python extensions, all symbols (except for 'init_cairo') are intended to be private, and a python C extension should have only one public symbol - the initialise module function - to help to avoid symbol name clashes with other extension modules. Some more information is described here: http://docs.python.org/ext/using-cobjects.html I think the problem is "Why is your system trying to access private symbols". I think, but don't know for sure, that other people have successfully ran pycairo on Mac OS X. I know that the pygtk 2.10.5 Python module uses 'export-symbols-regex' and a similar approach as pycairo, and seems to work OK. I don't use Mac OS X so can't investigate the problem, but I don't think removing 'export-symbols-regex' is correct. You could try installing using the setup.py - to see if this method works and which linker options it chooses, and update this bug report if you discover anything new.
When I build with setup.py the installed library works, which is good. *But* if I look with nm I can see that the _cairo.so it's installed has all the symbols public, just like my solution produced. That said, python setup.py build failed initially, due to this: iver[pycairo-1.4.0]% python setup.py build 16:51 cairo version >= 1.4.0 detected creating pycairo.pc running build running build_py creating build creating build/lib.macosx-10.5-i386-2.5 creating build/lib.macosx-10.5-i386-2.5/cairo copying cairo/__init__.py -> build/lib.macosx-10.5-i386-2.5/cairo running build_ext building 'cairo._cairo' extension creating build/temp.macosx-10.5-i386-2.5 creating build/temp.macosx-10.5-i386-2.5/cairo ...[snip]... gcc -Wl,-F. -bundle -undefined dynamic_lookup -arch i386 -arch ppc build/temp.macosx-10.5-i386-2.5/cairo/cairomodule.o build/temp.macosx-10.5-i386-2.5/cairo/pycairo-context.o build/temp.macosx-10.5-i386-2.5/cairo/pycairo-font.o build/temp.macosx-10.5-i386-2.5/cairo/pycairo-matrix.o build/temp.macosx-10.5-i386-2.5/cairo/pycairo-path.o build/temp.macosx-10.5-i386-2.5/cairo/pycairo-pattern.o build/temp.macosx-10.5-i386-2.5/cairo/pycairo-surface.o -L/opt/local/lib -L/usr/X11/lib -L/opt/local/lib -L/usr/X11/lib -lcairo -lSM -lICE -lfreetype -lz -lfontconfig -lexpat -lpng12 -lXrender -lX11 -o build/lib.macosx-10.5-i386-2.5/cairo/_cairo.so ld: warning in /opt/local/lib/libcairo.dylib, file is not of required architecture ld: warning in /opt/local/lib/libfreetype.dylib, file is not of required architecture ld: warning in /opt/local/lib/libz.dylib, file is not of required architecture ld: warning in /opt/local/lib/libfontconfig.dylib, file is not of required architecture ld: warning in /opt/local/lib/libexpat.dylib, file is not of required architecture ld: warning in /opt/local/lib/libpng12.dylib, file is not of required architecture ld: warning in /opt/local/lib/libXrender.dylib, file is not of required architecture iver[pycairo-1.4.0]% The problem here is that macports has not installed ppc compatible libraries for cairo etc. So I ran that last gcc call by hand removing the "-arch ppc" flag, then reran the build and it built okay. I'll happily admit that this may have caused the nmedit stage to be skipped, though at no point did I spot it geneting a symbol list. I appreciate my solution was probably not the right one, but it was just enough to get me going :) I need pycairo for work, so it was just to let me get going. Let me know if there's any more I can do to assist. Alas my knowledge of the Apple linker setup is not very much currently.
On my system (Linux) the configure and setup.py build methods produce slightly different results too. With the configure build, 'nm _cairo.so' shows the symbols are private: 000000000000a4d7 t PycairoContext_FromContext 000000000000addd t PycairoFontFace_FromFontFace 000000000000ac2c t PycairoFontOptions_FromFontOptions 000000000000b3aa t PycairoMatrix_FromMatrix 000000000000b9b3 t PycairoPath_FromPath 000000000000be4c t PycairoPattern_FromPattern 000000000000acc3 t PycairoScaledFont_FromScaledFont 000000000000c997 t PycairoSurface_FromSurface 000000000000dd7f t Pycairo_Check_Status 000000000000d1c0 T init_cairo With the setup.py build the symbols are public: 000000000000babb T PycairoContext_FromContext 000000000000c37a T PycairoFontFace_FromFontFace 000000000000c19f T PycairoFontOptions_FromFontOptions 000000000000c410 T PycairoMatrix_FromMatrix 000000000000ced9 T PycairoPath_FromPath 000000000000d361 T PycairoPattern_FromPattern 000000000000c24b T PycairoScaledFont_FromScaledFont 000000000000de98 T PycairoSurface_FromSurface 0000000000009522 T Pycairo_Check_Status 0000000000008950 T init_cairo I think this is because the functions listed should be declared 'static', as recommended by the manual reference I gave earlier. But since the module code is not a single file but spread over a number of files, and some of these functions are called from outside their own file, I needed to remove the 'static' declaration to get the module to compile, resulting in the functions inadvertently becoming public. The configure install method uses the 'export-symbols-regex' option to force them back to being private. But the setup.py method leaves them as public. Both methods (if they compile successfully) result in working pycairo modules, but the configure method is (theoretically) better since it only makes public the 'init_cairo' function. The distutils 'Extension' class accepts 'export_symbols' argument which limits which symbols are exported a Python extension. But the documentation says its not used on all platforms. When I try using export_symbols = 'init_cairo' in setup.py it does not prevent the other symbols from remaining public/global.
This looks like a similar problem I had with other modules on 10.5. In my case it was fixed by upgrading libtool to 1.5.26, which has a bunch of fixes for 10.5.
I see no evidence that this is a pycairo bug, just that pycairo exposes a bug on Mac OS X. The last comment suggests that the problem is a Mac OS X build environment problem, and is fixed using newer build tools.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.