1 ###########################################################################
5 # Copyright (c) Kitware Inc.
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
11 # http://www.apache.org/licenses/LICENSE-2.0.txt
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.
19 ###########################################################################
22 # ctkMacroWrapPythonQt
32 #! The different parameters are:
34 #! WRAPPING_NAMESPACE: Namespace that should contain the library. For example: org.commontk
36 #! TARGET ...........: Name of the wrapped library. For example: CTKWidget
38 #! SRCS_LIST_NAME ...: Name of the variable that should contain the generated wrapper source.
39 #! For example: KIT_PYTHONQT_SRCS
41 #! SOURCES ..........: List of source files that should be wrapped.
43 #! HAS_DECORATOR ....: Indicate if a custom PythonQt decorator header is expected.
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.
54 #! \ingroup CMakeUtilities
55 macro(ctkMacroWrapPythonQt WRAPPING_NAMESPACE TARGET SRCS_LIST_NAME SOURCES IS_WRAP_FULL HAS_DECORATOR)
59 message(FATAL_ERROR "IS_WRAP_FULL option is not supported anymore. See https://github.com/commontk/CTK/issues/449")
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")
73 foreach(FILE ${SOURCES})
75 set(skip_wrapping FALSE)
78 # Skip wrapping if file is NOT regular header
79 if(NOT ${FILE} MATCHES "^.*\\.[hH]$")
80 set(skip_wrapping TRUE)
82 message("${FILE}: skipping - Not a regular header")
88 # Skip wrapping if file is a pimpl header
89 if(${FILE} MATCHES "^.*_[pP]\\.[hH]$")
90 set(skip_wrapping TRUE)
92 message("${FILE}: skipping - Pimpl header (*._p.h)")
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)
106 message("${FILE}: skipping - WRAP_EXCLUDE")
111 # if we should wrap it
112 if(NOT skip_wrapping)
114 # compute the input filename
115 if(IS_ABSOLUTE ${FILE})
116 set(TMP_INPUT ${FILE})
118 set(TMP_INPUT ${CMAKE_CURRENT_SOURCE_DIR}/${FILE})
121 list(APPEND SOURCES_TO_WRAP ${TMP_INPUT})
125 # Convert wrapping namespace to subdir
126 string(REPLACE "." "_" WRAPPING_NAMESPACE_UNDERSCORE ${WRAPPING_NAMESPACE})
128 # Define wrap type and wrap intermediate directory
129 set(wrap_int_dir generated_cpp/${WRAPPING_NAMESPACE_UNDERSCORE}_${TARGET}/)
131 set(wrapper_module_init_cpp_filename ${wrap_int_dir}${WRAPPING_NAMESPACE_UNDERSCORE}_${TARGET}_module_init.cpp)
133 # Configure 'ctkMacroWrapPythonQtModuleInit.cpp.in' using TARGET, HAS_DECORATOR and
134 # WRAPPING_NAMESPACE_UNDERSCORE.
135 set(TARGET_CONFIG ${TARGET})
137 ${CTK_CMAKE_DIR}/ctkMacroWrapPythonQtModuleInit.cpp.in
138 ${wrapper_module_init_cpp_filename}
144 set(extra_args --extra-verbose)
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)
153 ${wrapper_init_cpp_filename}
154 ${wrapper_h_filename}
157 ${CTK_CMAKE_DIR}/ctkWrapPythonQt.py
158 COMMAND ${PYTHON_EXECUTABLE} ${CTK_CMAKE_DIR}/ctkWrapPythonQt.py
160 --namespace=${WRAPPING_NAMESPACE}
161 --output-dir=${CMAKE_CURRENT_BINARY_DIR}/${wrap_int_dir} ${extra_args}
163 COMMENT "PythonQt Wrapping - Generating ${wrapper_init_cpp_filename}"
166 if(CTK_QT_VERSION VERSION_GREATER "4")
167 qt5_wrap_cpp(${TARGET}_MOC_CXX ${CMAKE_CURRENT_BINARY_DIR}/${wrapper_h_filename})
169 QT4_WRAP_CPP(${TARGET}_MOC_CXX ${CMAKE_CURRENT_BINARY_DIR}/${wrapper_h_filename})
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)
179 # Create the Init File
180 set(${SRCS_LIST_NAME}
182 ${wrapper_init_cpp_filename}
183 ${wrapper_module_init_cpp_filename}
188 # Let's include the headers associated with PythonQt
190 find_package(PythonQt)
191 if(NOT PYTHONQT_FOUND)
192 message(FATAL_ERROR "error: PythonQt package is required to build ${TARGET}PythonQt")
194 include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHONQT_INCLUDE_DIR})