Skip to content

Commit 68358b3

Browse files
henryiiijcfr
andcommitted
feat: Add support for OUTPUT parameter
Co-authored-by: Jean-Christophe Fillion-Robin <[email protected]>
1 parent bc2df79 commit 68358b3

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

src/cython_cmake/cmake/UseCython.cmake

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# Cython_compile_pyx(<pyx_file>
1111
# [LANGUAGE C | CXX]
1212
# [CYTHON_ARGS <args> ...]
13+
# [OUTPUT <OutputFile>]
1314
# [OUTPUT_VARIABLE <OutputVariable>])
1415
#
1516
# Options:
@@ -23,10 +24,14 @@
2324
# Specify additional arguments for the cythonization process. Will default to
2425
# the ``CYTHON_ARGS`` variable if not specified.
2526
#
27+
# ``OUTPUT <OutputFile>``
28+
# Specify a specific path for the output file as ``<OutputFile>``. By
29+
# default, this will output into the current binary dir. A depfile will be
30+
# created alongside this file as well.
31+
#
2632
# ``OUTPUT_VARIABLE <OutputVariable>``
2733
# Set the variable ``<OutputVariable>`` in the parent scope to the path to the
28-
# generated source file. By default, ``<Name>`` is used as the output
29-
# variable name.
34+
# generated source file.
3035
#
3136
# Defined variables:
3237
#
@@ -72,7 +77,7 @@ endif()
7277

7378
function(Cython_compile_pyx)
7479
set(_options )
75-
set(_one_value LANGUAGE OUTPUT_VARIABLE)
80+
set(_one_value LANGUAGE OUTPUT OUTPUT_VARIABLE)
7681
set(_multi_value CYTHON_ARGS)
7782

7883
cmake_parse_arguments(_args
@@ -174,7 +179,15 @@ function(Cython_compile_pyx)
174179
set(generated_files)
175180

176181
list(GET _source_files 0 _source_file)
177-
_set_output(${_source_file} generated_file)
182+
183+
# Place the cython files in the current binary dir if no path given
184+
if(NOT _args_OUTPUT)
185+
_set_output(${_source_file} _args_OUTPUT)
186+
elseif(NOT IS_ABSOLUTE ${_args_OUTPUT})
187+
set(_args_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_args_OUTPUT}")
188+
endif()
189+
190+
set(generated_file ${_args_OUTPUT})
178191
_compile_pyx(${_source_file} ${generated_file})
179192
list(APPEND generated_files ${generated_file})
180193

tests/packages/simple/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ find_package(
88
find_package(Cython MODULE REQUIRED VERSION 3.0)
99
include(UseCython)
1010

11-
cython_compile_pyx(simple.pyx LANGUAGE C OUTPUT_VARIABLE simple_c)
11+
cython_compile_pyx(simple.pyx
12+
LANGUAGE C
13+
# OUTPUT_ARG
14+
OUTPUT_VARIABLE simple_c
15+
)
1216

1317
python_add_library(simple MODULE "${simple_c}" WITH_SOABI)
1418

tests/test_package.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from __future__ import annotations
22

33
import importlib.metadata
4+
import shutil
45
import zipfile
56
from pathlib import Path
67

8+
import pytest
79
from scikit_build_core.build import build_wheel
810

911
import cython_cmake as m
@@ -15,7 +17,7 @@ def test_version():
1517
assert importlib.metadata.version("cython_cmake") == m.__version__
1618

1719

18-
def test_scikit_build_core(monkeypatch, tmp_path):
20+
def test_simple(monkeypatch, tmp_path):
1921
monkeypatch.chdir(DIR / "packages/simple")
2022
build_dir = tmp_path / "build"
2123

@@ -30,3 +32,42 @@ def test_scikit_build_core(monkeypatch, tmp_path):
3032
build_files = {x.name for x in build_dir.iterdir()}
3133
assert "simple.c.dep" in build_files
3234
assert "simple.c" in build_files
35+
36+
37+
@pytest.mark.parametrize("output_arg", ["empty", "relative", "absolute"])
38+
def test_output_argument(monkeypatch, tmp_path, output_arg):
39+
package_dir = tmp_path / "pkg2"
40+
shutil.copytree(DIR / "packages/simple", package_dir)
41+
monkeypatch.chdir(package_dir)
42+
43+
build_dir = tmp_path / "build"
44+
45+
output_values = {
46+
"empty": "",
47+
"relative": "relative-custom.c",
48+
"absolute": (build_dir / "absolute-custom.c").as_posix(),
49+
}
50+
51+
cmakelists = Path("CMakeLists.txt")
52+
txt = cmakelists.read_text().replace(
53+
"# OUTPUT_ARG", f'OUTPUT "{output_values[output_arg]}"'
54+
)
55+
cmakelists.write_text(txt)
56+
57+
wheel = build_wheel(
58+
str(tmp_path), {"build-dir": str(build_dir), "wheel.license-files": []}
59+
)
60+
61+
with zipfile.ZipFile(tmp_path / wheel) as f:
62+
file_names = set(f.namelist())
63+
assert len(file_names) == 4
64+
65+
generated_file = {
66+
"empty": "simple.c",
67+
"relative": "relative-custom.c",
68+
"absolute": "absolute-custom.c",
69+
}[output_arg]
70+
71+
build_files = {x.name for x in build_dir.iterdir()}
72+
assert f"{generated_file}.dep" in build_files
73+
assert generated_file in build_files

0 commit comments

Comments
 (0)