CMakeLists.txt 7.19 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
2
3
4
5
6
7
8
9
10
11
12
13
IF(NOT DEFINED OPENMESH_BUILD_PYTHON_BINDINGS)
	SET(OPENMESH_BUILD_PYTHON_BINDINGS TRUE CACHE BOOL "Enable or disable building the Python Bindings.")
ENDIF()

IF(NOT DEFINED OPENMESH_BUILD_PYTHON_UNIT_TESTS)
	SET(OPENMESH_BUILD_PYTHON_UNIT_TESTS FALSE CACHE BOOL "Enable or disable building the Python unit tests.")
ENDIF()

IF(NOT DEFINED OPENMESH_PYTHON_VERSION)
	SET(OPENMESH_PYTHON_VERSION "2.7" CACHE STRING "Choose the Python version that is used to build the Python Bindings.")
ENDIF()

IF(OPENMESH_BUILD_PYTHON_BINDINGS)
14
15
16
17
	# Create log file
	SET(PYTHONLOG "${CMAKE_CURRENT_BINARY_DIR}/PythonLog.txt")
	FILE(WRITE ${PYTHONLOG} "")

Jan Möbius's avatar
Jan Möbius committed
18
	# Look for the python libs
Isaak Lim's avatar
Isaak Lim committed
19
	MESSAGE(STATUS "Looking for PythonLibs")
Jan Möbius's avatar
Jan Möbius committed
20
21
22
	FIND_PACKAGE(PythonLibs ${OPENMESH_PYTHON_VERSION} QUIET)

	IF(PYTHONLIBS_FOUND)
Isaak Lim's avatar
Isaak Lim committed
23
		MESSAGE(STATUS "Looking for PythonLibs -- found")
Jan Möbius's avatar
Jan Möbius committed
24
25

		# Determine the name of the python component
Isaak Lim's avatar
Isaak Lim committed
26
27
28
		STRING(REGEX MATCH "^[0-9]+\\.[0-9]+" PYTHON_VERSION_MAJOR_MINOR ${PYTHONLIBS_VERSION_STRING})
		STRING(REGEX REPLACE "\\." "" PYTHON_VERSION_MAJOR_MINOR ${PYTHON_VERSION_MAJOR_MINOR})
		STRING(REGEX MATCH "^[0-9]" PYTHON_VERSION_MAJOR ${PYTHON_VERSION_MAJOR_MINOR})
Jan Möbius's avatar
Jan Möbius committed
29
30
31

		MESSAGE(STATUS "Looking for Boost Python")

Isaak Lim's avatar
Isaak Lim committed
32
33
34
35
		SET(BOOST_PYTHON_COMPONENT_NAMES "python-py${PYTHON_VERSION_MAJOR_MINOR}" "python${PYTHON_VERSION_MAJOR}" "python")

		FOREACH(NAME ${BOOST_PYTHON_COMPONENT_NAMES})
			IF(NOT Boost_FOUND)
36
				FILE(APPEND ${PYTHONLOG} "Looking for component ${NAME}\n")
Isaak Lim's avatar
Isaak Lim committed
37
38
39
				FIND_PACKAGE(Boost QUIET COMPONENTS ${NAME})
			ENDIF()
		ENDFOREACH()
Jan Möbius's avatar
Jan Möbius committed
40

41
42
		FILE(APPEND ${PYTHONLOG} "\n")

Jan Möbius's avatar
Jan Möbius committed
43
44
45
46
		IF(Boost_FOUND)
			MESSAGE(STATUS "Looking for Boost Python -- found")
			MESSAGE(STATUS "Checking the Boost Python configuration")

47
48
			SET(CMAKE_TRY_COMPILE_CONFIGURATION "Release")
			
Jan Möbius's avatar
Jan Möbius committed
49
50
51
52
53
54
55
			TRY_COMPILE(
				COMPILE_WORKS
				${CMAKE_CURRENT_BINARY_DIR}
				${CMAKE_CURRENT_SOURCE_DIR}/Example/
				Example
				CMAKE_FLAGS
					"-DINCLUDE_DIRECTORIES:STRING=${PYTHON_INCLUDE_DIRS};${Boost_INCLUDE_DIRS}"
56
					"-DLINK_DIRECTORIES:STRING=${Boost_LIBRARY_DIRS}"
Jan Möbius's avatar
Jan Möbius committed
57
					"-DLINK_LIBRARIES:STRING=${PYTHON_LIBRARIES};${Boost_LIBRARIES}"
58
				OUTPUT_VARIABLE OUTPUT_TRY_COMPILE
Jan Möbius's avatar
Jan Möbius committed
59
60
			)

61
62
63
64
65
			FILE(APPEND ${PYTHONLOG} "INCLUDE_DIRECTORIES: ${PYTHON_INCLUDE_DIRS};${Boost_INCLUDE_DIRS}\n")
			FILE(APPEND ${PYTHONLOG} "LINK_DIRECTORIES: ${Boost_LIBRARY_DIRS}\n")
			FILE(APPEND ${PYTHONLOG} "LINK_LIBRARIES: ${PYTHON_LIBRARIES};${Boost_LIBRARIES}\n\n")
			FILE(APPEND ${PYTHONLOG} "${OUTPUT_TRY_COMPILE}")

Jan Möbius's avatar
Jan Möbius committed
66
67
			IF(COMPILE_WORKS)
				# Look for the python interpreter to check if the example works
68

69
70
				# strip version string of any characters (e.g.  # '+') than 0-9 and .
				STRING(REGEX REPLACE "[^ 0-9 | \\.]" "" PYTHONLIBS_VERSION_STRING_STRIPPED ${PYTHONLIBS_VERSION_STRING})
71
				FIND_PACKAGE(PythonInterp ${PYTHONLIBS_VERSION_STRING_STRIPPED} QUIET)
Jan Möbius's avatar
Jan Möbius committed
72
73

				IF(PYTHONINTERP_FOUND)
74
75
76
77
78
79
80
					
					IF(MSVC)
						SET(PYTHON_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_TRY_COMPILE_CONFIGURATION}")
					ELSE()
						SET(PYTHON_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}")
					ENDIF()
					
Jan Möbius's avatar
Jan Möbius committed
81
82
					EXECUTE_PROCESS(
						COMMAND ${PYTHON_EXECUTABLE} -c "from example import *; greet(); planet = World()"
83
						WORKING_DIRECTORY ${PYTHON_WORKING_DIR}
Jan Möbius's avatar
Jan Möbius committed
84
85
86
87
88
89
90
91
92
93
						RESULT_VARIABLE PYTHON_WORKS
						OUTPUT_QUIET
						ERROR_QUIET
					)

					IF(PYTHON_WORKS EQUAL 0)

						### EVERYTHING WORKS ###

						MESSAGE(STATUS "Checking the Boost Python configuration -- done")
94

95
						IF(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" AND ${Boost_VERSION} VERSION_LESS 105600)
Jan Möbius's avatar
Jan Möbius committed
96
97
98
99
100
							MESSAGE("There are known issues with Clang and Boost Python 1.55 and below.")
							MESSAGE("Please consider updating Boost Python.")
						ENDIF()

						SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Build/python/)
101
						FILE(MAKE_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
Jan Möbius's avatar
Jan Möbius committed
102
103

						FILE(GLOB SOURCES *.cc *hh)
104
105
106
107

						INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ../)
						LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})

Jan Möbius's avatar
Jan Möbius committed
108
109
						ADD_LIBRARY(openmesh SHARED ${SOURCES})

110
111
						install(TARGETS openmesh DESTINATION ${ACG_PROJECT_LIBDIR}/python )

Jan Möbius's avatar
Jan Möbius committed
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
						TARGET_LINK_LIBRARIES(
							openmesh
							OpenMeshCore
							OpenMeshTools
							${Boost_LIBRARIES}
							${PYTHON_LIBRARIES}
						)

						SET_TARGET_PROPERTIES(
							openmesh
							PROPERTIES
							PREFIX ""
							DEBUG_POSTFIX ""
							RELEASE_POSTFIX ""
						)

						IF(APPLE)
							SET_TARGET_PROPERTIES(openmesh PROPERTIES SUFFIX ".so")
Isaak Lim's avatar
Isaak Lim committed
130
131
132
							IF (NOT (CMAKE_MAJOR_VERSION LESS 3))
								SET_TARGET_PROPERTIES(openmesh PROPERTIES MACOSX_RPATH TRUE)
							ENDIF()
Jan Möbius's avatar
Jan Möbius committed
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
						ENDIF()

						IF(WIN32)
							SET_TARGET_PROPERTIES(openmesh PROPERTIES SUFFIX ".pyd")
							SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")

							SET(OUTPUTS openmesh.exp openmesh.lib openmesh.pyd)

							FOREACH(FILE ${OUTPUTS})
								ADD_CUSTOM_COMMAND(
									TARGET openmesh POST_BUILD
									COMMAND ${CMAKE_COMMAND} -E copy
										${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${FILE}
										${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
								)
							ENDFOREACH()
						ENDIF()

						IF(OPENMESH_BUILD_PYTHON_UNIT_TESTS)
							SET(UNITTEST_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Python-Unittests/)

							# Copy unit tests
							FILE(GLOB UNITTESTS Unittests/*.py)
							FOREACH(TEST ${UNITTESTS})
								FILE(COPY ${TEST} DESTINATION ${UNITTEST_OUTPUT_DIRECTORY})
							ENDFOREACH()

							# Copy test files
							FILE(GLOB TESTFILES ${PROJECT_SOURCE_DIR}/src/Unittests/TestFiles/*(.off|.obj|.mtl|.stl|.ply|.om))
							FOREACH(FILE ${TESTFILES})
								FILE(COPY ${FILE} DESTINATION ${UNITTEST_OUTPUT_DIRECTORY})
							ENDFOREACH()

							# Copy library
							IF(WIN32)
								FOREACH(FILE ${OUTPUTS})
									ADD_CUSTOM_COMMAND(
										TARGET openmesh POST_BUILD
										COMMAND ${CMAKE_COMMAND} -E copy
											${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${FILE}
											${UNITTEST_OUTPUT_DIRECTORY}
									)
								ENDFOREACH()
							ELSE()
								ADD_CUSTOM_COMMAND(
									TARGET openmesh POST_BUILD
									COMMAND ${CMAKE_COMMAND} -E copy
										${CMAKE_BINARY_DIR}/Build/python/openmesh.so
										${UNITTEST_OUTPUT_DIRECTORY}
								)
							ENDIF()

							ADD_TEST(
								NAME Python_tests
								WORKING_DIRECTORY ${UNITTEST_OUTPUT_DIRECTORY}
								COMMAND ${PYTHON_EXECUTABLE} -m unittest discover --verbose
							)
						ENDIF()

					ELSE()
						MESSAGE("Checking the Boost Python configuration failed!")
						MESSAGE("Reason: An error occurred while running a small Boost Python test project.")
						MESSAGE("Make sure that your Python and Boost Python libraries match.")
						MESSAGE("Skipping Python Bindings.")
					ENDIF()
				ELSE()
					MESSAGE("Checking the Boost Python configuration failed!")
					MESSAGE("Reason: Python Interpreter ${PYTHONLIBS_VERSION_STRING} not found.")
					MESSAGE("Skipping Python Bindings.")
				ENDIF()
			ELSE()
				MESSAGE("Checking the Boost Python configuration failed!")
				MESSAGE("Reason: Building a small Boost Python test project failed.")
				MESSAGE("Make sure that your Python and Boost Python libraries match.")
				MESSAGE("Skipping Python Bindings.")
			ENDIF()
		ELSE()
			MESSAGE("Boost Python not found! Skipping Python Bindings.")
		ENDIF()
	ELSE()
Isaak Lim's avatar
Isaak Lim committed
213
		MESSAGE("PythonLibs not found! Skipping Python Bindings.")
Jan Möbius's avatar
Jan Möbius committed
214
215
	ENDIF()
ENDIF()