CTK 0.1.0
The Common Toolkit is a community effort to provide support code for medical image analysis, surgical navigation, and related projects.
ctkMacroWrapPythonQt.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# ctkMacroWrapPythonQt
23#
24
25#!
26#! Depends on:
27#! PythonQt
28#! PythonInterp
29#!
30
31#!
32#! The different parameters are:
33#!
34#! WRAPPING_NAMESPACE: Namespace that should contain the library. For example: org.commontk
35#!
36#! TARGET ...........: Name of the wrapped library. For example: CTKWidget
37#!
38#! SRCS_LIST_NAME ...: Name of the variable that should contain the generated wrapper source.
39#! For example: KIT_PYTHONQT_SRCS
40#!
41#! SOURCES ..........: List of source files that should be wrapped.
42#!
43#! HAS_DECORATOR ....: Indicate if a custom PythonQt decorator header is expected.
44#!
45
46#!
47#! LOG FILE:
48#! File ctkMacroWrapPythonQt_log.txt will be created in the current directory.
49#! It will contain the list of file and the reason why a given class hasn't been wrapped.
50#!
51
52set(verbose 0)
53
54#! \ingroup CMakeUtilities
55macro(ctkMacroWrapPythonQt WRAPPING_NAMESPACE TARGET SRCS_LIST_NAME SOURCES IS_WRAP_FULL HAS_DECORATOR)
56
57 # Sanity check
58 if(IS_WRAP_FULL)
59 message(FATAL_ERROR "IS_WRAP_FULL option is not supported anymore. See https://github.com/commontk/CTK/issues/449")
60 endif()
61
62 # TODO: this find package seems not to work when called form a superbuild, but the call is needed
63 # in general to find the python interpreter. In CTK, the toplevel CMakeLists.txt does the find
64 # package so this is a no-op. Other uses of this file may need to have this call so it is still enabled.
65 find_package(PythonInterp)
66 if(NOT PYTHONINTERP_FOUND)
67 message(FATAL_ERROR "PYTHON_EXECUTABLE not specified or inexistent when calling ctkMacroWrapPythonQt")
68 endif()
69
70 set(SOURCES_TO_WRAP)
71
72 # For each class
73 foreach(FILE ${SOURCES})
74
75 set(skip_wrapping FALSE)
76
77 if(NOT skip_wrapping)
78 # Skip wrapping if file is NOT regular header
79 if(NOT ${FILE} MATCHES "^.*\\.[hH]$")
80 set(skip_wrapping TRUE)
81 if(verbose)
82 message("${FILE}: skipping - Not a regular header")
83 endif()
84 endif()
85 endif()
86
87 if(NOT skip_wrapping)
88 # Skip wrapping if file is a pimpl header
89 if(${FILE} MATCHES "^.*_[pP]\\.[hH]$")
90 set(skip_wrapping TRUE)
91 if(verbose)
92 message("${FILE}: skipping - Pimpl header (*._p.h)")
93 endif()
94 endif()
95 endif()
96
97 if(NOT skip_wrapping)
98 # Skip wrapping if file should excluded
99 set(skip_wrapping TRUE)
100 get_source_file_property(TMP_WRAP_EXCLUDE ${FILE} WRAP_EXCLUDE)
101 if(NOT TMP_WRAP_EXCLUDE)
102 set(skip_wrapping FALSE)
103 endif()
104 if(skip_wrapping)
105 if(verbose)
106 message("${FILE}: skipping - WRAP_EXCLUDE")
107 endif()
108 endif()
109 endif()
110
111 # if we should wrap it
112 if(NOT skip_wrapping)
113
114 # compute the input filename
115 if(IS_ABSOLUTE ${FILE})
116 set(TMP_INPUT ${FILE})
117 else()
118 set(TMP_INPUT ${CMAKE_CURRENT_SOURCE_DIR}/${FILE})
119 endif()
120
121 list(APPEND SOURCES_TO_WRAP ${TMP_INPUT})
122 endif()
123 endforeach()
124
125 # Convert wrapping namespace to subdir
126 string(REPLACE "." "_" WRAPPING_NAMESPACE_UNDERSCORE ${WRAPPING_NAMESPACE})
127
128 # Define wrap type and wrap intermediate directory
129 set(wrap_int_dir generated_cpp/${WRAPPING_NAMESPACE_UNDERSCORE}_${TARGET}/)
130
131 set(wrapper_module_init_cpp_filename ${wrap_int_dir}${WRAPPING_NAMESPACE_UNDERSCORE}_${TARGET}_module_init.cpp)
132
133 # Configure 'ctkMacroWrapPythonQtModuleInit.cpp.in' using TARGET, HAS_DECORATOR and
134 # WRAPPING_NAMESPACE_UNDERSCORE.
135 set(TARGET_CONFIG ${TARGET})
136 configure_file(
137 ${CTK_CMAKE_DIR}/ctkMacroWrapPythonQtModuleInit.cpp.in
138 ${wrapper_module_init_cpp_filename}
139 @ONLY
140 )
141
142 set(extra_args)
143 if(verbose)
144 set(extra_args --extra-verbose)
145 endif()
146
147 # Custom command allow to generate ${WRAPPING_NAMESPACE_UNDERSCORE}_${TARGET}_init.cpp and
148 # associated wrappers ${WRAPPING_NAMESPACE_UNDERSCORE}_${TARGET}.cpp
149 set(wrapper_init_cpp_filename ${wrap_int_dir}${WRAPPING_NAMESPACE_UNDERSCORE}_${TARGET}_init.cpp)
150 set(wrapper_h_filename ${wrap_int_dir}${WRAPPING_NAMESPACE_UNDERSCORE}_${TARGET}.h)
151 add_custom_command(
152 OUTPUT
153 ${wrapper_init_cpp_filename}
154 ${wrapper_h_filename}
155 DEPENDS
156 ${SOURCES_TO_WRAP}
157 ${CTK_CMAKE_DIR}/ctkWrapPythonQt.py
158 COMMAND ${PYTHON_EXECUTABLE} ${CTK_CMAKE_DIR}/ctkWrapPythonQt.py
159 --target=${TARGET}
160 --namespace=${WRAPPING_NAMESPACE}
161 --output-dir=${CMAKE_CURRENT_BINARY_DIR}/${wrap_int_dir} ${extra_args}
162 ${SOURCES_TO_WRAP}
163 COMMENT "PythonQt Wrapping - Generating ${wrapper_init_cpp_filename}"
164 VERBATIM
165 )
166 if(CTK_QT_VERSION VERSION_GREATER "4")
167 qt5_wrap_cpp(${TARGET}_MOC_CXX ${CMAKE_CURRENT_BINARY_DIR}/${wrapper_h_filename})
168 else()
169 QT4_WRAP_CPP(${TARGET}_MOC_CXX ${CMAKE_CURRENT_BINARY_DIR}/${wrapper_h_filename})
170 endif()
171
172 # The following files are generated
173 set_source_files_properties(
174 ${wrapper_init_cpp_filename}
175 ${wrapper_h_filename}
176 ${wrapper_module_init_cpp_filename}
177 PROPERTIES GENERATED TRUE)
178
179 # Create the Init File
180 set(${SRCS_LIST_NAME}
181 ${${SRCS_LIST_NAME}}
182 ${wrapper_init_cpp_filename}
183 ${wrapper_module_init_cpp_filename}
184 ${${TARGET}_MOC_CXX}
185 )
186
187 #
188 # Let's include the headers associated with PythonQt
189 #
190 find_package(PythonQt)
191 if(NOT PYTHONQT_FOUND)
192 message(FATAL_ERROR "error: PythonQt package is required to build ${TARGET}PythonQt")
193 endif()
194 include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHONQT_INCLUDE_DIR})
195
196endmacro()
197