| Summary: | pycairo links with all symbols marked private in _cairo.so on Mac OS X 10.5 | ||
|---|---|---|---|
| Product: | pycairo | Reporter: | Michael Dales <mwd> |
| Component: | general | Assignee: | Steve Chaplin <d74n5pohf9> |
| Status: | RESOLVED NOTOURBUG | QA Contact: | |
| Severity: | critical | ||
| Priority: | high | CC: | dmacks |
| Version: | unspecified | ||
| Hardware: | x86 (IA32) | ||
| OS: | Mac OS X (All) | ||
| Whiteboard: | |||
| i915 platform: | i915 features: | ||
|
Description
Michael Dales
2007-11-07 05:11:36 UTC
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.