CTK 0.1.0
The Common Toolkit is a community effort to provide support code for medical image analysis, surgical navigation, and related projects.
Loading...
Searching...
No Matches
ctkMacroBuildLibWrapper.cmake
Go to the documentation of this file.
1###########################################################################
2#
3# Library: CTK
4#
5# Copyright (c) Kitware Inc.
6#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0.txt
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18#
19###########################################################################
20
21#
22# Depends on:
23# CTK/CMake/ctkMacroParseArguments.cmake
24#
25
26
27#! When CTK is built as shared library, the following macro builds a python module
28#! associated with the generated PythonQt wrappers. When loaded, it will
29#! dynamically loads both the (1) generated decorators and the (2) hand written one.
30#! On the other hand, when CTK is built statically, it creates a
31#! static library providing a initialization function that will allow to load
32#! both (1) and (2).
33
34# Function copied from https://github.com/scikit-build/scikit-build/pull/299
35# XXX Update this CMake module to use function from scikit-build to build the wrapper
36function(_ctk_set_python_extension_symbol_visibility _target)
37 if(PYTHON_VERSION_MAJOR VERSION_GREATER 2)
38 set(_modinit_prefix "PyInit_")
39 else()
40 set(_modinit_prefix "init")
41 endif()
42 if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
43 set_target_properties(${_target} PROPERTIES LINK_FLAGS
44 "/EXPORT:${_modinit_prefix}${_target}"
45 )
46 elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
47 set(_script_path
48 ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_target}-version-script.map
49 )
50 file(WRITE ${_script_path}
51 "{global: ${_modinit_prefix}${_target}; local: *; };"
52 )
53 set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS
54 " -Wl,--version-script=${_script_path}"
55 )
56 endif()
57endfunction()
58
59#! \ingroup CMakeAPI
60macro(ctkMacroBuildLibWrapper)
61 ctkMacroParseArguments(MY
62 "NAMESPACE;TARGET;SRCS;WRAPPER_LIBRARY_TYPE;ARCHIVE_OUTPUT_DIRECTORY;LIBRARY_OUTPUT_DIRECTORY;RUNTIME_OUTPUT_DIRECTORY;INSTALL_BIN_DIR;INSTALL_LIB_DIR"
63 "NO_INSTALL"
64 ${ARGN}
65 )
66
67 # Sanity checks
68 if(NOT DEFINED MY_TARGET)
69 message(FATAL_ERROR "NAME is mandatory")
70 endif()
71 if(NOT DEFINED MY_WRAPPER_LIBRARY_TYPE OR "${MY_WRAPPER_LIBRARY_TYPE}" STREQUAL "SHARED")
72 set(MY_WRAPPER_LIBRARY_TYPE "MODULE")
73 endif()
74
75 if(NOT DEFINED MY_NAMESPACE)
76 set(MY_NAMESPACE "org.commontk")
77 endif()
78 foreach(type RUNTIME LIBRARY ARCHIVE)
79 if(NOT DEFINED MY_${type}_OUTPUT_DIRECTORY)
80 set(MY_${type}_OUTPUT_DIRECTORY ${CMAKE_${type}_OUTPUT_DIRECTORY})
81 endif()
82 endforeach()
83 if(NOT DEFINED MY_INSTALL_BIN_DIR)
84 set(MY_INSTALL_BIN_DIR ${CTK_INSTALL_BIN_DIR})
85 endif()
86 if(NOT DEFINED MY_INSTALL_LIB_DIR)
87 set(MY_INSTALL_LIB_DIR ${CTK_INSTALL_LIB_DIR})
88 endif()
89
90 # Define library name
91 set(lib_name ${MY_TARGET})
92
93 # Include dirs
94 set(my_includes
95 ${CMAKE_CURRENT_SOURCE_DIR}
96 ${CMAKE_CURRENT_BINARY_DIR}
97 )
98
99 # Since the PythonQt decorator depends on PythonQt, Python and VTK, let's link against
100 # these ones to avoid complaints of MSVC
101 # Note: "LINK_DIRECTORIES" has to be invoked before "ADD_LIBRARY"
102 set(my_EXTRA_PYTHON_LIBRARIES ${PYTHON_LIBRARY} ${PYTHONQT_LIBRARIES})
103
104 # Does a header having the expected filename exists ?
105 string(REGEX REPLACE "^CTK" "ctk" lib_name_lc_ctk ${lib_name})
106 set(DECORATOR_HEADER ${lib_name_lc_ctk}PythonQtDecorators.h)
107 set(HAS_DECORATOR FALSE)
108
109 set(_msg "Looking for decorator header ${DECORATOR_HEADER}")
110 message(STATUS "${_msg}")
111 set(_status "Not found")
112 if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${DECORATOR_HEADER})
113 set(HAS_DECORATOR TRUE)
114 set(DECORATOR_HEADER ${DECORATOR_HEADER})
115 set_source_files_properties(${DECORATOR_HEADER} WRAP_EXCLUDE)
116 set(_status "Found")
117 endif()
118 message(STATUS "${_msg} - ${_status}")
119 #message("path/to/DECORATOR_HEADER:${CMAKE_CURRENT_SOURCE_DIR}/${DECORATOR_HEADER}")
120
121 set(KIT_PYTHONQT_SRCS) # Clear variable
122 ctkMacroWrapPythonQt(${MY_NAMESPACE} ${lib_name}
123 KIT_PYTHONQT_SRCS "${MY_SRCS}" FALSE ${HAS_DECORATOR})
124 if(HAS_DECORATOR)
125 list(APPEND KIT_PYTHONQT_SRCS ${DECORATOR_HEADER})
126 if (CTK_QT_VERSION VERSION_GREATER "4")
127 qt5_wrap_cpp(KIT_PYTHONQT_SRCS ${DECORATOR_HEADER} OPTIONS -f${DECORATOR_HEADER})
128 else()
129 QT4_WRAP_CPP(KIT_PYTHONQT_SRCS ${DECORATOR_HEADER} OPTIONS -f${DECORATOR_HEADER})
130 endif()
131 endif()
132 add_library(${lib_name}PythonQt ${MY_WRAPPER_LIBRARY_TYPE} ${KIT_PYTHONQT_SRCS})
133 target_link_libraries(${lib_name}PythonQt ${lib_name} ${my_EXTRA_PYTHON_LIBRARIES})
134 if(MY_WRAPPER_LIBRARY_TYPE STREQUAL "STATIC")
135 if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit
136 set_target_properties(${lib_name}PythonQt PROPERTIES COMPILE_FLAGS "-fPIC")
137 endif()
138 endif()
139 if(MY_WRAPPER_LIBRARY_TYPE STREQUAL "MODULE")
140 # Make sure that no prefix is set on the library
141 set_target_properties(${lib_name}PythonQt PROPERTIES PREFIX "")
142 # Python extension modules on Windows must have the extension ".pyd"
143 # instead of ".dll" as of Python 2.5. Older python versions do support
144 # this suffix.
145 # See http://docs.python.org/faq/windows.html#is-a-pyd-file-the-same-as-a-dll
146 if(WIN32 AND NOT CYGWIN)
147 set_target_properties(${lib_name}PythonQt PROPERTIES SUFFIX ".pyd")
148 endif()
149 endif()
150 _ctk_set_python_extension_symbol_visibility(${lib_name}PythonQt)
151 set_target_properties(${lib_name}PythonQt PROPERTIES
152 RUNTIME_OUTPUT_DIRECTORY "${MY_RUNTIME_OUTPUT_DIRECTORY}"
153 LIBRARY_OUTPUT_DIRECTORY "${MY_LIBRARY_OUTPUT_DIRECTORY}"
154 ARCHIVE_OUTPUT_DIRECTORY "${MY_ARCHIVE_OUTPUT_DIRECTORY}"
155 )
156
157 # Set labels associated with the target.
158 set_target_properties(${lib_name}PythonQt PROPERTIES LABELS ${lib_name})
159
160 # Update list of libraries wrapped with PythonQt
161 set(CTK_WRAPPED_LIBRARIES_PYTHONQT
162 ${CTK_WRAPPED_LIBRARIES_PYTHONQT} ${lib_name}
163 CACHE INTERNAL "CTK libraries wrapped using PythonQt" FORCE)
164
165 # Install rules
166 if(NOT MY_NO_INSTALL AND MY_WRAPPER_LIBRARY_TYPE STREQUAL "MODULE")
167 install(TARGETS ${lib_name}PythonQt
168 RUNTIME DESTINATION ${MY_INSTALL_LIB_DIR} COMPONENT RuntimePlugins
169 LIBRARY DESTINATION ${MY_INSTALL_LIB_DIR} COMPONENT RuntimePlugins
170 ARCHIVE DESTINATION ${MY_INSTALL_LIB_DIR} COMPONENT Development)
171 endif()
172
173endmacro()
174
175