22#
33# The following functions are defined:
44#
5+ # .. cmake:command:: Cython_compile_pyx
6+ #
7+ # Create a custom rule to generate the source code for a Python extension module
8+ # using cython.
9+ #
10+ # Cython_compile_pyx(<CythonInput>
11+ # [TARGET_LANGUAGE C | CXX]
12+ # [LANGUAGE_LEVEL 2 | 3 | 3str]
13+ # [OUTPUT_VAR <OutputVar>])
14+ #
15+ # Options:
16+ #
17+ # ``TARGET_LANGUAGE [C | CXX]``
18+ # Force the generation of either a C or C++ file. By default, a C file is
19+ # generated, unless the C language is not enabled for the project; in this
20+ # case, a C++ file is generated by default.
21+ #
22+ # ``LANGUAGE_LEVEL [2 | 3 | 3str]``
23+ # Force compilation using either Python-2, Python-3 or Python-3str syntax and
24+ # code semantics.
25+ # By default, Python-3str syntax and semantics are used if the major version
26+ # of Python found is 3 and Cython >=3 is used. Otherwise, Python-2 syntax and
27+ # semantics are used.
28+ # Using the Python-3str syntax and semantics means there cython does not assume
29+ # unicode is used by by default for string literals under Python 2
30+ #
31+ # ``OUTPUT_VAR <OutputVar>``
32+ # Set the variable ``<OutputVar>`` in the parent scope to the path to the
33+ # generated source file. By default, ``<Name>`` is used as the output
34+ # variable name.
35+ #
36+ # Defined variables:
37+ #
38+ # ``<OutputVar>``
39+ # The path of the generated source file.
40+ #
41+ # Usage example:
42+ #
43+ # .. code-block:: cmake
44+ #
45+ # find_package(Cython)
46+ #
47+ # Cython_compile_pyx(_hello.pyx
48+ # OUTPUT_VAR _hello_source_file
49+ # )
50+ #
51+ # Python_add_library(_hello
52+ # MODULE ${_hello_source_file}
53+ # WITH_SOABI
54+ # )
55+ #
56+ #
557# .. cmake:command:: add_cython_target
658#
759# Create a custom rule to generate the source code for a Python extension module
3082#
3183# Options:
3284#
33- # ``TARGET_LANGUAGE [C | CXX]``
34- # Force the generation of either a C or C++ file. By default, a C file is
35- # generated, unless the C language is not enabled for the project; in this
36- # case, a C++ file is generated by default.
37- #
38- # ``C | CXX`` (deprecated)
85+ # ``C | CXX``
3986# Force the generation of either a C or C++ file. By default, a C file is
4087# generated, unless the C language is not enabled for the project; in this
4188# case, a C++ file is generated by default.
4289#
43- # ``LANGUAGE_LEVEL [2 | 3 | 3str]``
44- # Force compilation using either Python-2, Python-3 or Python-3str syntax and
45- # code semantics.
46- # By default, Python-3str syntax and semantics are used if the major version
47- # of Python found is 3 and Cython >=3 is used. Otherwise, Python-2 syntax and
48- # semantics are used.
49- # Using the Python-3str syntax and semantics means there cython does not assume
50- # unicode is used by by default for string literals under Python 2
51- #
52- # ``PY2 | PY3`` (deprecated)
90+ # ``PY2 | PY3``
5391# Force compilation using either Python-2 or Python-3 syntax and code
5492# semantics. By default, Python-2 syntax and semantics are used if the major
5593# version of Python found is 2. Otherwise, Python-3 syntax and semantics are
73111# ``CYTHON_FLAGS``
74112# Additional flags to pass to the Cython compiler.
75113#
76- # Example usage
77- # ^^^^^^^^^^^^^
114+ # Usage example:
78115#
79116# .. code-block:: cmake
80117#
103140# limitations under the License.
104141#=============================================================================
105142
106- # Configuration options.
107- set (CYTHON_ANNOTATE OFF
108- CACHE BOOL "Create an annotated .html file when compiling *.pyx." )
109-
110- set (CYTHON_FLAGS "" CACHE STRING
111- "Extra flags to the cython compiler." )
112- mark_as_advanced (CYTHON_ANNOTATE CYTHON_FLAGS)
113143
114144function (add_cython_target _name)
115- set (_deprecated_options C CXX PY2 PY3)
116- set (_options )
117- set (_one_value TARGET_LANGUAGE OUTPUT_VAR)
145+ set (_options C CXX PY2 PY3)
146+ set (_one_value OUTPUT_VAR)
118147 set (_multi_value )
119148
120149 cmake_parse_arguments (_args
121- "${_options} ${_deprecated_options} "
150+ "${_options} "
122151 "${_one_value} "
123152 "${_multi_value} "
124153 ${ARGN}
125154 )
126155
127- # Support deprecated options: C, CXX
128- if (NOT _args_TARGET_LANGUAGE)
129- if (_args_C)
130- set (_args_TARGET_LANGUAGE "C" )
131- endif ()
132- if (_args_CXX)
133- set (_args_TARGET_LANGUAGE "CXX" )
134- endif ()
156+ # Configuration options.
157+ set (CYTHON_ANNOTATE OFF
158+ CACHE BOOL "Create an annotated .html file when compiling *.pyx." )
159+
160+ set (CYTHON_FLAGS "" CACHE STRING
161+ "Extra flags to the cython compiler." )
162+ mark_as_advanced (CYTHON_ANNOTATE CYTHON_FLAGS)
163+
164+ if (_args_C)
165+ set (_target_language "C" )
166+ endif ()
167+ if (_args_CXX)
168+ set (_target_language "CXX" )
135169 endif ()
136170
137- # Support deprecated options: PY2, PY3
138- if (NOT _args_LANGUAGE_LEVEL)
139- if (_args_PY2)
140- set (_args_LANGUAGE_LEVEL "2" )
141- endif ()
142- if (_args_PY3)
143- set (_args_LANGUAGE_LEVEL "3" )
144- endif ()
171+ if (_args_PY2)
172+ set (_language_level "2" )
173+ endif ()
174+ if (_args_PY3)
175+ set (_language_level "3" )
145176 endif ()
146177
147178 list (GET _args_UNPARSED_ARGUMENTS 0 _arg0)
@@ -165,6 +196,57 @@ function(add_cython_target _name)
165196 endif ()
166197 endif ()
167198
199+ # Set additional flags.
200+ set (_cython_args)
201+ if (CYTHON_ANNOTATE)
202+ list (APPEND _cython_args "--annotate" )
203+ endif ()
204+ if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR
205+ CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" )
206+ list (APPEND _cython_args
207+ "--gdb"
208+ "--line-directives"
209+ )
210+ endif ()
211+ string (STRIP "${CYTHON_FLAGS} " _stripped_cython_flags)
212+ if (_stripped_cython_flags)
213+ string (REGEX REPLACE " " ";" CYTHON_FLAGS_LIST "${_stripped_cython_flags} " )
214+ list (APPEND _cython_args ${CYTHON_FLAGS_LIST} )
215+ endif ()
216+
217+ Cython_compile_pyx(
218+ TARGET_LANGUAGE ${_target_language}
219+ LANGUAGE_LEVEL ${_language_level}
220+ CYTHON_ARGS ${_cython_args}
221+ OUTPUT_VAR ${_args_OUTPUT_VAR}
222+ ${_source_file}
223+ )
224+
225+ if (_args_OUTPUT_VAR)
226+ set (${_args_OUTPUT_VAR} ${${_args_OUTPUT_VAR} } PARENT_SCOPE)
227+ endif ()
228+ endfunction ()
229+
230+ function (Cython_compile_pyx)
231+ set (_options )
232+ set (_one_value LANGUAGE_LEVEL TARGET_LANGUAGE OUTPUT_VAR)
233+ set (_multi_value CYTHON_ARGS)
234+
235+ cmake_parse_arguments (_args
236+ "${_options} "
237+ "${_one_value} "
238+ "${_multi_value} "
239+ ${ARGN}
240+ )
241+
242+ # Get source file location
243+ set (_source_files ${_args_UNPARSED_ARGUMENTS} )
244+ list (GET _source_files 0 _source_file)
245+ list (LENGTH _source_files _source_file_count)
246+ if (_source_file_count GREATER 1)
247+ message (AUTHOR_WARNING "Cython_compile_pyx supports compiling only one file: ${_source_files} " )
248+ endif ()
249+
168250 # Set target language
169251 get_property (_languages GLOBAL PROPERTY ENABLED_LANGUAGES )
170252 set (_target_language ${_args_TARGET_LANGUAGE} )
@@ -204,6 +286,7 @@ function(add_cython_target _name)
204286
205287 set (_language_level_arg "${_language_level_${_language_level} _arg}" )
206288
289+ cmake_path(GET _source_file STEM _name)
207290 set (generated_file "${CMAKE_CURRENT_BINARY_DIR} /${_name} .${_target_language_extension} " )
208291 set_source_files_properties (${generated_file} PROPERTIES GENERATED TRUE )
209292
@@ -225,33 +308,14 @@ function(add_cython_target _name)
225308 set (_depfile ${generated_file} .dep)
226309 set (_depfile_arg "-M" )
227310
228- # Set additional flags.
229- set (annotate_arg "" )
230- if (CYTHON_ANNOTATE)
231- set (annotate_arg "--annotate" )
232- endif ()
233-
234- set (cython_debug_arg "" )
235- set (line_directives_arg "" )
236- if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR
237- CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" )
238- set (cython_debug_arg "--gdb" )
239- set (line_directives_arg "--line-directives" )
240- endif ()
241-
242- string (REGEX REPLACE " " ";" CYTHON_FLAGS_LIST "${CYTHON_FLAGS} " )
243-
244311 # Add the command to run the compiler.
245312 add_custom_command (
246313 OUTPUT ${generated_file}
247314 COMMAND ${CYTHON_EXECUTABLE}
248315 ARGS
249316 ${_target_language_arg}
250317 ${_language_level_arg}
251- ${annotate_arg}
252- ${cython_debug_arg}
253- ${line_directives_arg}
254- ${CYTHON_FLAGS_LIST}
318+ ${_args_CYTHON_ARGS}
255319 ${_depfile_arg}
256320 ${pyx_location}
257321 --output -file ${generated_file}
@@ -263,20 +327,4 @@ function(add_cython_target _name)
263327 COMMENT ${comment}
264328 )
265329
266- # NOTE(opadron): I thought about making a proper target, but after trying it
267- # out, I decided that it would be far too convenient to use the same name as
268- # the target for the extension module (e.g.: for single-file modules):
269- #
270- # ...
271- # add_cython_target(_module.pyx)
272- # add_library(_module ${_module})
273- # ...
274- #
275- # The above example would not be possible since the "_module" target name
276- # would already be taken by the cython target. Since I can't think of a
277- # reason why someone would need the custom target instead of just using the
278- # generated file directly, I decided to leave this commented out.
279- #
280- # add_custom_target(${_name} DEPENDS ${generated_file})
281330endfunction ()
282-
0 commit comments