4949# )
5050#
5151# Python_add_library(_hello
52- # MODULE ${_hello_source_files}
52+ # MODULE "${_hello_source_file}"
5353# WITH_SOABI
5454# )
5555#
@@ -79,16 +79,19 @@ if(CMAKE_VERSION VERSION_LESS "3.8")
7979endif ()
8080
8181function (Cython_transpile)
82- set (_options )
83- set (_one_value LANGUAGE OUTPUT OUTPUT_VARIABLE )
84- set (_multi_value CYTHON_ARGS)
85-
86- cmake_parse_arguments (_args
87- "${_options} "
88- "${_one_value} "
89- "${_multi_value} "
90- ${ARGN}
82+ cmake_parse_arguments (
83+ PARSE_ARGV 0
84+ CYTHON
85+ ""
86+ "OUTPUT;LANGUAGE;OUTPUT_VARIABLE"
87+ "CYTHON_ARGS"
9188 )
89+ set (ALL_INPUT ${CYTHON_UNPARSED_ARGUMENTS} )
90+ list (LENGTH ALL_INPUT INPUT_LENGTH)
91+ if (NOT INPUT_LENGTH EQUAL 1)
92+ message (FATAL_ERROR "One and only one input file must be specified, got '${ALL_INPUT} '" )
93+ endif ()
94+ list (GET ALL_INPUT 0 INPUT )
9295
9396 if (DEFINED CYTHON_EXECUTABLE)
9497 set (_cython_command "${CYTHON_EXECUTABLE} " )
@@ -101,142 +104,101 @@ function(Cython_transpile)
101104 endif ()
102105
103106 # Default to CYTHON_ARGS if argument not specified
104- if (NOT _args_CYTHON_ARGS AND DEFINED CYTHON_ARGS)
105- set (_args_CYTHON_ARGS "${CYTHON_ARGS} " )
106- endif ()
107-
108- # Get input
109- set (_source_files ${_args_UNPARSED_ARGUMENTS} )
110- list (LENGTH _source_files input_length)
111- if (NOT input_length EQUAL 1)
112- message (FATAL_ERROR "One and only one input file must be specified, got '${_source_files} '" )
107+ if (NOT CYTHON_CYTHON_ARGS AND DEFINED CYTHON_ARGS)
108+ set (CYTHON_CYTHON_ARGS "${CYTHON_ARGS} " )
113109 endif ()
114110
115- function (_transpile _source_file generated_file language )
116-
117- if (language STREQUAL "C" )
118- set (_language_arg "" )
119- elseif (language STREQUAL "CXX" )
120- set (_language_arg "--cplus" )
121- else ()
122- message (FATAL_ERROR "_transpile language must be one of C or CXX" )
123- endif ()
124-
125- set_source_files_properties (${generated_file} PROPERTIES GENERATED TRUE )
126-
127- # Generated depfile is expected to have the ".dep" extension and be located along
128- # side the generated source file.
129- set (_depfile ${generated_file} .dep)
130- set (_depfile_arg "-M" )
131-
132- # Normalize the input path
133- get_filename_component (_source_file "${_source_file} " ABSOLUTE )
134-
135- # Pretty-printed output names
136- file (RELATIVE_PATH generated_file_relative
137- ${CMAKE_BINARY_DIR} ${generated_file} )
138- file (RELATIVE_PATH source_file_relative
139- ${CMAKE_SOURCE_DIR} ${_source_file} )
140- set (comment "Generating ${_language} source '${generated_file_relative} ' from '${source_file_relative} '" )
141-
142- # Get output directory to ensure its exists
143- get_filename_component (output_directory "${generated_file} " DIRECTORY )
144-
145- get_source_file_property (pyx_location ${_source_file} LOCATION )
146-
147- # Add the command to run the compiler.
148- add_custom_command (
149- OUTPUT ${generated_file}
150- COMMAND
151- ${CMAKE_COMMAND} -E make_directory ${output_directory}
152- COMMAND
153- ${_cython_command}
154- ${_language_arg}
155- "${_args_CYTHON_ARGS} "
156- ${_depfile_arg}
157- ${pyx_location}
158- --output -file ${generated_file}
159- COMMAND_EXPAND_LISTS
160- MAIN_DEPENDENCY
161- ${_source_file}
162- DEPFILE
163- ${_depfile}
164- VERBATIM
165- COMMENT ${comment}
166- )
167- endfunction ()
168-
169- function (_set_output _input_file _language _output_var)
170- if (_language STREQUAL "C" )
171- set (_language_extension "c" )
172- elseif (_language STREQUAL "CXX" )
173- set (_language_extension "cxx" )
174- else ()
175- message (FATAL_ERROR "_set_output language must be one of C or CXX" )
176- endif ()
177-
178- # Can use cmake_path for CMake 3.20+
179- # cmake_path(GET _input_file STEM basename)
180- get_filename_component (_basename "${_input_file} " NAME_WE )
181-
182- if (IS_ABSOLUTE ${_input_file} )
183- file (RELATIVE_PATH _input_relative ${CMAKE_CURRENT_SOURCE_DIR} ${_input_file} )
184- else ()
185- set (_input_relative ${_input_file} )
186- endif ()
187-
188- get_filename_component (_output_relative_dir "${_input_relative} " DIRECTORY )
189- string (REPLACE "." "_" _output_relative_dir "${_output_relative_dir} " )
190- if (_output_relative_dir)
191- set (_output_relative_dir "${_output_relative_dir} /" )
192- endif ()
193-
194- set (${_output_var} "${CMAKE_CURRENT_BINARY_DIR} /${_output_relative_dir}${_basename} .${_language_extension} " PARENT_SCOPE)
195- endfunction ()
196-
197- set (generated_files)
198-
199- list (GET _source_files 0 _source_file)
200-
201111 # Set target language
202- set (_language ${_args_LANGUAGE} )
203- if (NOT _language)
112+ if (NOT CYTHON_LANGUAGE)
204113 get_property (_languages GLOBAL PROPERTY ENABLED_LANGUAGES )
114+
205115 if ("C" IN_LIST _languages AND "CXX" IN_LIST _languages)
206116 # Try to compute language. Returns falsy if not found.
207- _cython_compute_language(_language ${_source_file} )
117+ _cython_compute_language(CYTHON_LANGUAGE ${INPUT} )
118+ message (STATUS "${CYTHON_LANGUAGE} " )
208119 elseif ("C" IN_LIST _languages)
209120 # If only C is enabled globally, assume C
210- set (_language "C" )
121+ set (CYTHON_LANGUAGE C )
211122 elseif ("CXX" IN_LIST _languages)
212123 # Likewise for CXX
213- set (_language " CXX" )
124+ set (CYTHON_LANGUAGE CXX)
214125 else ()
215126 message (FATAL_ERROR "LANGUAGE keyword required if neither C nor CXX enabled globally" )
216127 endif ()
217128 endif ()
218129
219- if (NOT _language MATCHES "^(C|CXX)$" )
220- message (FATAL_ERROR "Cython_transpile LANGUAGE must be one of C or CXX" )
130+ # Default to C if not found
131+ if (NOT CYTHON_LANGUAGE)
132+ set (CYTHON_LANGUAGE C)
133+ endif ()
134+
135+ if (CYTHON_LANGUAGE STREQUAL C)
136+ set (language_arg "" )
137+ set (language_ext ".c" )
138+ elseif (CYTHON_LANGUAGE STREQUAL CXX)
139+ set (language_arg "--cplus" )
140+ set (language_ext ".cxx" )
141+ else ()
142+ message (FATAL_ERROR "cython_compile_pyx LANGUAGE must be one of C or CXX" )
221143 endif ()
222144
223145 # Place the cython files in the current binary dir if no path given
224- if (NOT _args_OUTPUT)
225- _set_output(${_source_file} ${_language} _args_OUTPUT)
226- elseif (NOT IS_ABSOLUTE ${_args_OUTPUT} )
227- set (_args_OUTPUT "${CMAKE_CURRENT_BINARY_DIR} /${_args_OUTPUT} " )
146+ # Can use cmake_path for CMake 3.20+
147+ if (NOT CYTHON_OUTPUT)
148+ get_filename_component (basename "${INPUT} " NAME_WE )
149+
150+ set (CYTHON_OUTPUT "${CMAKE_CURRENT_BINARY_DIR} /${basename}${language_ext} " )
151+ elseif (NOT IS_ABSOLUTE CYTHON_OUTPUT)
152+ set (CYTHON_OUTPUT "${CMAKE_CURRENT_BINARY_DIR} /${CYTHON_OUTPUT} " )
228153 endif ()
229154
230- set (generated_file ${_args_OUTPUT} )
231- _transpile( ${_source_file} ${generated_file} ${_language} )
232- list ( APPEND generated_files ${generated_file} )
155+ # Normalize the input path
156+ get_filename_component ( INPUT " ${INPUT} " ABSOLUTE )
157+ set_source_files_properties ( " ${INPUT} " PROPERTIES GENERATED TRUE )
233158
234159 # Output variable only if set
235- if (_args_OUTPUT_VARIABLE)
236- set (_output_variable ${_args_OUTPUT_VARIABLE} )
237- set (${_output_variable} ${generated_files} PARENT_SCOPE)
160+ if (CYTHON_OUTPUT_VARIABLE)
161+ set (${CYTHON_OUTPUT_VARIABLE} "${CYTHON_OUTPUT} " PARENT_SCOPE)
238162 endif ()
239163
164+ # Generated depfile is expected to have the ".dep" extension and be located
165+ # along side the generated source file.
166+ set (depfile_path "${CYTHON_OUTPUT} .dep" )
167+
168+ # Pretty-printed output name
169+ file (RELATIVE_PATH generated_file_relative "${CMAKE_BINARY_DIR} " "${CYTHON_OUTPUT} " )
170+ file (RELATIVE_PATH input_file_relative "${CMAKE_SOURCE_DIR} " "${INPUT} " )
171+
172+ # Add the command to run the compiler.
173+ add_custom_command (
174+ OUTPUT
175+ "${CYTHON_OUTPUT} "
176+ "${depfile_path} "
177+ COMMAND
178+ ${_cython_command}
179+ ${language_arg}
180+ ${CYTHON_CYTHON_ARGS}
181+ --depfile
182+ "${INPUT} "
183+ --output -file "${CYTHON_OUTPUT} "
184+ MAIN_DEPENDENCY
185+ "${INPUT} "
186+ DEPFILE
187+ "${depfile_path} "
188+ VERBATIM
189+ COMMENT
190+ "Cythonizing source ${input_file_relative} to output ${generated_file_relative} "
191+ )
192+
193+ endfunction ()
194+
195+ function (_cython_compute_language OUTPUT_VARIABLE FILENAME)
196+ file (READ "${FILENAME} " FILE_CONTENT)
197+ set (REGEX_PATTERN [=[^[[:space:]]*#[[:space:]]*distutils:.*language[[:space:]]*=[[:space:]]*(c\\+\\+|c)]=])
198+ string (REGEX MATCH "${REGEX_PATTERN} " MATCH_RESULT "${FILE_CONTENT} " )
199+ string (TOUPPER "${MATCH_RESULT} " LANGUAGE_NAME)
200+ string (REPLACE "+" "X" LANGUAGE_NAME "${LANGUAGE_NAME} " )
201+ set (${OUTPUT_VARIABLE} ${LANGUAGE_NAME} PARENT_SCOPE)
240202endfunction ()
241203
242204function (_cython_compute_language OUTPUT_VARIABLE FILENAME)
0 commit comments