cmake支持SWIG的使用,因此在这里总结下在CMAKE中使用swig的方法,以KMCLib为例子。

由于CMake与SWIG的相互支持,使得在cmake脚本中直接定义封装模块的构建成为可能,KMCLib中也是使用这种方式直接使用swig进行自动封装。也就是在生成的Makefile中包含了使用swig命令封装库文件。

在这里我主要参考了swig文档中关于cmake的部分cmake文档中使用swig的部分

还是上例子吧

简单的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# This is a CMake example for Python

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 "")

SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(example python example.i example.cxx)
SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})

每条语句分析:

1
FIND_PACKAGE(SWIG REQUIRED)

寻找swig有没有安装在本机上,如果没有,由于指定了REQUIRED参数,cmake会产生一个fatal error然后停止构建。


1
INCLUDE(${SWIG_USE_FILE})  

载入预定义的cmake模块


1
FIND_PACKAGE(PythonLibs)  

查看python是否安装并生成几个变量确定python的头文件以及库文件在哪里。变量列表:


PYTHONLIBS_FOUND - have the Python libs been found
PYTHON_LIBRARIES - path to the python library
PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated)
PYTHON_INCLUDE_DIRS - path to where Python.h is found
PYTHON_DEBUG_LIBRARIES - path to the debug library (deprecated)
PYTHONLIBS_VERSION_STRING - version of the Python libs found (since CMake 2.8.8)


1
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})

将python的include路径加入编译的include路径中。


1
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})

将当前路径加入到编译的include路径中。


1
SET(CMAKE_SWIG_FLAGS "")

CMAKE_SWIG_FLAGS可以用来设置给所有要调用swig的地方的参数,例如-python, -c++


1
2
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall")

如果某个swig生成的原代码需要某种参数就要通过这个macro进行设置,上面的第一个应该就相当于在swig的参数中添加-c++以生成cxx文件。


1
SWIG_ADD_MODULE(example python example.i example.cxx)

这个cmake函数是定义swig生成的最终模块的名称和封装的语言


1
SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})

将库与swig模块一起链接。上文已说明PYTHON_LIBRARY变量存放的是python库的路径。

KMCLib中CMakeLists.txt中的swig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# Make sure the swig package is loaded.
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})

include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories( ${KMCLib_SOURCE_DIR}/src )

# Set the flags.
set(CMAKE_SWIG_FLAGS "")

# Set the properties for the interface file.
set_source_files_properties(backend.i PROPERTIES CPLUSPLUS ON)
set_source_files_properties(backend.i PROPERTIES SWIG_FLAGS "")

...

# Add the target.
swig_add_module( Backend python backend.i )

# -----------------------------------------------------------------------------
# LINK
# -----------------------------------------------------------------------------

message( STATUS "Creating makefiles for system: ${CMAKE_SYSTEM}")
# For Mac OS X
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")

# To force a Mac OSX with macports Python, use with -DMACPORT=TRUE
if (MACPORT)
set(CMAKE_LIBRARY_PATH "/opt/local/Library/Frameworks")
message( STATUS "Looking for libraries in ${CMAKE_LIBRARY_PATH}" )
endif()

find_library( PYTHON_LIB python )
message( STATUS "Using python library ${PYTHON_LIB}")
swig_link_libraries( Backend ${PYTHON_LIB} src )

# For Linux (Ubuntu 12.04 LTS)
else()#${CMAKE_SYSTEM_NAME} MATCHES "Linux")
swig_link_libraries( Backend src )
endif()

按照上面的介绍,这里的cmake也不难理解了。

Comments