[CMake] python wrappers through xcode
Antoine PREVOT
tonio_lesec at yahoo.fr
Wed Jul 30 15:39:25 EDT 2008
Hi,
First of all, english is not my native language, so I hope i'll be
understandable. Don't hesitate to correct me (it's the only way to
progress), or ask for rephrasing if it's not. And since it's my first
post here, i'll be happy to produce some personal introduction if needed !
- Environnement :
OSX Tiger (darwin 8.11.1) - XCode 2.4.1 - CMake 2.4 - SWIG 1.3.36 hand
compiled from standard tgz.
- Project context (optional) :
To make it simple, I am programming a fluid simulation library. It's
goal is to produce a liquid/smoke surface behavior (a mesh and a
pressure/density/velocity field). This library is meant to be called
through two main ways : direct library link (opengl test/demo
applications), and python wrappers (Maya/Renderman scripted plug-ins).
To be totally independent, the fluid simulator only produces basic
topology and "aspect aims" in a gegneric structure (a render heap
similar to the scene tree internally implemented by Maya). This
structure is declared/handled in a separate library.
From here, an opengl program only have to read this heap and compute
corresponding GL primitives. A maya plug-in will only retrieve the mesh
topology (vectors/edges/faces) to build it's own MFnMesh object. A
renderman interface will only read density values (since renderman is
able to generate implicit surfaces alone) etc.
It's, obviously, a cross-platform project ... but i'll focus on xcode
for now. The reason i'm describing all this annoying stuff is that I
still don't know if it's the proper way to make things, but a
svn/cmake/swig combination seemed appropriated.
- What I tried and didn't happen to succeed (here comes the flop) :
The step I'm stuck in, is the way to automatically generate python
wrappers through CMake build / XCode compilation.
Consider I have a root project, a toolkit library, a subpart of this lib
(utils), and an existing not-so-c++-style-but-well-named example.cpp
file in this subpart I want to expose to python. The project tree could be :
trunk\CMakeLists.txt
trunk\src\CMakeLists.txt
trunk\src\mysdk\CMakeLists.txt
trunk\src\mysdk\utils\example.cpp
trunk\src\mysdk\utils\example.i
(pretty simple, doesn't it ?)
Root CMakeLists contains platform specific operations, project
configuration and libraries research, especialy python and swig :
******************** trunk\CMakeLists.txt
...
# common issue on osx while using non standard compilation
# SWIG_DIR must be manually specified
SET(SWIG_DIR "/usr/local")
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS "-c++")
...
Sources CMakeLists will only point on subprojects, libraries etc. :
******************** trunk\src\CMakeLists.txt
SUBDIRS(
mysdk
)
Library CMakeList will declare it's own contents and resources, and
eventually python wrappers (here we are) :
******************** trunk\src\mysdk\CMakeLists.txt
SET(MYSDK_UTILS_SOURCES
utils/example.cpp
utils/example.i
)
SET_SOURCE_FILES_PROPERTIES(utils/example.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(utils/example.i PROPERTIES SWIG_FLAGS
"-includeall")
SET(MYSDK_SOURCES ${MYSDK_UTILS_SOURCES})
SOURCE_GROUP(Utils FILES ${MYSDK_UTILS_SOURCES})
ADD_LIBRARY(mysdk ${MYSDK_SOURCES})
SWIG_ADD_MODULE(example python utils/example.i utils/example.cpp)
SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})
example.cpp is a simple function, c/p powered :
******************** trunk\src\mysdk\utils\example.cpp
int cube(int n)
{
return (n * n * n);
}
example.i is the corresponding wrapper declaration :
******************** trunk\src\mysdk\utils\example.i
%module example
%{
extern int cube( int n );
%}
%include example.cpp
Manually swigged/compiled (see
http://www.penzilla.net/tutorials/python/swig/), everything is fine (it
would be a shame) :
# example_wrap.cxx creation
/usr/local/bin/swig -python -c++ example.i
# compilation
gcc -c example.cpp example_wrap.cxx -I
/Library/Frameworks/Python.framework/Versions/2.4/include/python2.4/
# link
ld -bundle -flat_namespace -undefined suppress -o _example.so example.o
example_wrap.o
python can access this module and use the wrapped function :
me#> python
>>> import _example
>>> _example.cube(2)
8
>>>
- The issue
The xcode project generated is quite strange (ccmake -G"Xcode") :
1/ example.cpp & example.i have duplicated entries (but it's definitely
the same file appearing twice)
2/ an extra _example library is created (besides the mmsdk one),
targeting an _example.so output (fine!), but this lib :
- contains an empty Utils folder (wow, what a coincidence :')
- attempts to source an examplePYTHON_wrap.cxx file (which obviously
doesnt exist)
Manually creating this cxx file with swig from the original sources
location, then moving it to the generated build/macosx-xcode/[...]
folder eventually do the job, and I could write a corresponding
cross-platform script to do it but ... whats the point on using CMake
that way ? :-/
I guess i'm missing something so big I can't see it, just here, right
under my nose, but i had so much headaches having svn, cmake and swig up
in this crappy undocumented os that I can't figure out what is happening
now. I wish I were still on my sweet old debian :)
I will take any advice, throught, even rtfm-style atomization, thanks in
advance !
Tonio
If you can read this, you don't need glasses.
More information about the CMake
mailing list