Skip to content

Commit 2e2b43b

Browse files
authored
[Build] Use CMAKE_ARGS directly, drop legacy QUADRANTS_CMAKE_ARGS (#753)
1 parent 472d291 commit 2e2b43b

8 files changed

Lines changed: 49 additions & 37 deletions

File tree

.github/workflows/scripts/qd_build/cmake.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ def __init__(self, environ_name):
3030
self.option_definitions = {
3131
"CMAKE_EXPORT_COMPILE_COMMANDS": ("Generate compile_commands.json", False, ""),
3232
}
33+
# CMAKE_ARGS entries we don't parse into definitions, kept verbatim for writeback().
34+
self.passthrough = ""
3335

3436
self.finalized = False
3537

@@ -42,6 +44,12 @@ def collect_options(self, *files: str) -> None:
4244

4345
def parse_initial_args(self) -> None:
4446
args = os.environ.get(self.environ_name, "")
47+
# DEF_RE only understands `-D<ALLCAPS>[:BOOL]=<value>` entries (the options we manage and
48+
# render below). Everything else in CMAKE_ARGS -- CMake generators (`-GNinja`), typed cache
49+
# entries (`-DCMAKE_BUILD_TYPE:STRING=Debug`), lowercase-named or space-containing defines --
50+
# must be preserved verbatim, else writeback() would silently drop it before scikit-build-core
51+
# sees CMAKE_ARGS. Stash the unparsed remainder (matched entries blanked out) and re-emit it.
52+
self.passthrough = " ".join(DEF_RE.sub(" ", args).split())
4553
for name, value in DEF_RE.findall(args):
4654
self.set(name, value)
4755

@@ -129,13 +137,17 @@ def print_summary(self, rendered) -> None:
129137
def writeback(self) -> None:
130138
rendered = self.render()
131139
self.print_summary(rendered)
132-
value = " ".join([v for _, v, _ in rendered])
140+
# Rendered options first, then the verbatim passthrough captured in parse_initial_args. The
141+
# two sets are disjoint (parsed entries are blanked out of passthrough), so there is no
142+
# duplicate-cache-var ambiguity for CMake to resolve.
143+
parts = [v for _, v, _ in rendered]
144+
if self.passthrough:
145+
parts.append(self.passthrough)
146+
value = " ".join(parts)
147+
# CMAKE_ARGS is scikit-build-core's standard CMake-args passthrough, and it is also what we parse on input, so
148+
# writing it back makes the environment exported by `build.py wheel`, `-w`, and `--shell` directly usable by the
149+
# build with no further bridging.
133150
os.environ[self.environ_name] = value
134-
# scikit-build-core reads CMake args from CMAKE_ARGS, not the legacy QUADRANTS_CMAKE_ARGS.
135-
# Mirror the rendered args there so the environment exported by `build.py wheel`, `-w`, and
136-
# `--shell` is directly usable -- no manual `export CMAKE_ARGS="$QUADRANTS_CMAKE_ARGS"` step.
137-
if self.environ_name == "QUADRANTS_CMAKE_ARGS":
138-
os.environ["CMAKE_ARGS"] = value
139151
self.finalized = True
140152

141153
def __setitem__(self, name: str, value: Union[str, bool]) -> None:
@@ -145,10 +157,10 @@ def __getitem__(self, name: str) -> Union[str, bool]:
145157
return self.definitions[name]
146158

147159

148-
cmake_args = CMakeArgsManager("QUADRANTS_CMAKE_ARGS")
160+
cmake_args = CMakeArgsManager("CMAKE_ARGS")
149161

150162

151-
@banner("Parsing QUADRANTS_CMAKE_ARGS")
163+
@banner("Parsing CMAKE_ARGS")
152164
def _init_cmake_args():
153165
cmake_args.collect_options("CMakeLists.txt", *glob.glob("cmake/*.cmake"))
154166
cmake_args.parse_initial_args()

.github/workflows/scripts/qd_build/entry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
# -- code --
2424
@banner("Build Quadrants Wheel")
2525
def build_wheel(python: Command) -> None:
26-
# cmake_args.writeback() populates both QUADRANTS_CMAKE_ARGS and (for scikit-build-core) CMAKE_ARGS.
26+
# cmake_args.writeback() renders the effective options into CMAKE_ARGS for scikit-build-core.
2727
cmake_args.writeback()
2828

2929
plat = None

.github/workflows/scripts_new/clang_tidy/2_build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
set -ex
44

5-
export QUADRANTS_CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
5+
export CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
66
./build.py wheel

.github/workflows/scripts_new/linux/2_build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ export PATH=${LLVM_DIR}/bin:$PATH
88
which clang
99
clang --version
1010

11-
export QUADRANTS_CMAKE_ARGS="-DQD_WITH_VULKAN:BOOL=ON -DQD_WITH_AMDGPU:BOOL=ON -DQD_WITH_CUDA:BOOL=ON -DQD_BUILD_TESTS:BOOL=ON"
11+
export CMAKE_ARGS="-DQD_WITH_VULKAN:BOOL=ON -DQD_WITH_AMDGPU:BOOL=ON -DQD_WITH_CUDA:BOOL=ON -DQD_BUILD_TESTS:BOOL=ON"
1212
./build.py wheel

.github/workflows/scripts_new/macosx/2_build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
set -ex
44

5-
export QUADRANTS_CMAKE_ARGS="-DQD_WITH_VULKAN:BOOL=ON -DQD_WITH_METAL:BOOL=ON -DQD_BUILD_TESTS:BOOL=ON"
5+
export CMAKE_ARGS="-DQD_WITH_VULKAN:BOOL=ON -DQD_WITH_METAL:BOOL=ON -DQD_BUILD_TESTS:BOOL=ON"
66
./build.py wheel

.github/workflows/scripts_new/manylinux_wheel/2_build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ echo "Detected platform: $PLATFORM"
1919
export PATH="$PWD/taichi-llvm-15.0.7-linux-${PLATFORM}/bin:$PATH"
2020

2121
# Taichi build options
22-
export QUADRANTS_CMAKE_ARGS="-DQD_WITH_VULKAN:BOOL=ON -DQD_WITH_CUDA:BOOL=ON -DQD_WITH_AMDGPU:BOOL=ON -DQD_BUILD_TESTS:BOOL=ON"
22+
export CMAKE_ARGS="-DQD_WITH_VULKAN:BOOL=ON -DQD_WITH_CUDA:BOOL=ON -DQD_WITH_AMDGPU:BOOL=ON -DQD_BUILD_TESTS:BOOL=ON"
2323

2424
# GCC toolset include paths
2525
inc_base="/opt/rh/gcc-toolset-14/root/usr/include/c++/14"

.github/workflows/scripts_new/win/2_build.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ $ErrorActionPreference = "Stop"
22
Set-PSDebug -Trace 1
33
trap { Write-Error $_; exit 1 }
44

5-
$env:GSTAICHI_CMAKE_ARGS = "-DQD_WITH_VULKAN:BOOL=ON -DQD_WITH_AMDGPU:BOOL=ON -DQD_WITH_CUDA:BOOL=ON -DQD_BUILD_TESTS:BOOL=ON"
5+
$env:CMAKE_ARGS = "-DQD_WITH_VULKAN:BOOL=ON -DQD_WITH_AMDGPU:BOOL=ON -DQD_WITH_CUDA:BOOL=ON -DQD_BUILD_TESTS:BOOL=ON"
66
python build.py

docs/source/user_guide/contributing.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Contributing to quadrants
1+
# Advanced: Contributing to quadrants
22

33
## Good practice reminder
44

@@ -49,15 +49,15 @@ uv pip install --group dev --group test
4949

5050
`build.py` is a python script to automatically set up the build environment for you before invoking the build commands:
5151

52-
* `LLVM libraries`: downloads an archive for `LLVM` libraries, decompresses it and sets `LLVM_DIR`.
52+
* `LLVM libraries`: downloads an archive for [LLVM](https://llvm.org/) libraries (a library for building compilers), decompresses it and sets `LLVM_DIR`.
5353
* `clang`: depending on the platform, download `clang` or just check if available with the right version.
5454

5555
`build.py` can be used at least two ways:
5656

5757
* `build.py wheel` to build the wheel (via [scikit-build-core](https://scikit-build-core.readthedocs.io/en/latest/), i.e. `pip wheel`)
5858
* `build.py --shell` to enter a shell with environment variables set up as with `build.py wheel` in order to let you invoke yourself the commands.
5959

60-
For incremental development, do an editable install (scikit-build-core "redirect" mode: the compiled core is installed and rebuilt on demand, Python edits are live):
60+
For incremental development, do an editable install ([scikit-build-core](https://scikit-build-core.readthedocs.io/en/latest/) "redirect" mode: the compiled core is installed and rebuilt on demand, Python edits are live):
6161

6262
```
6363
./build.py --shell # run a new shell with environment variables
@@ -72,7 +72,7 @@ source env.sh
7272
pip install --no-build-isolation -e . -Ceditable.rebuild=true
7373
```
7474

75-
`build.py` exports both the legacy `QUADRANTS_CMAKE_ARGS` and the `CMAKE_ARGS` that scikit-build-core actually reads, so sourcing `env.sh` (or using `--shell`) is enough -- no manual `export CMAKE_ARGS="$QUADRANTS_CMAKE_ARGS"` step is needed.
75+
`build.py` reads and exports `CMAKE_ARGS` (scikit-build-core's CMake-args passthrough), so sourcing `env.sh` (or using `--shell`) is enough to make the configured options available to the build.
7676

7777
## Building the package for release purposes
7878

@@ -84,13 +84,13 @@ To build the release package:
8484

8585
We use `cmake` to build the C++ core. scikit-build-core puts the CMake build tree under `build/{wheel_tag}`, where the wheel tag encodes the Python version and host platform. For example: `build/cp310-cp310-linux_x86_64`.
8686

87-
You can modify the cmake options to your liking in order to enable or disable some features you need or don't need. To discover them, you can use `ccmake`:
87+
You can modify the cmake options to your liking in order to enable or disable some features you need or don't need. To discover them, you can use [ccmake](https://cmake.org/cmake/help/latest/manual/ccmake.1.html):
8888

8989
```
9090
ccmake build/cp310-cp310-linux_x86_64
9191
```
9292

93-
You could then set the environment variable `CMAKE_ARGS` (scikit-build-core's CMake-args passthrough) to configure the build. `build.py` also accepts the legacy `QUADRANTS_CMAKE_ARGS` and forwards it to `CMAKE_ARGS`. For instance, to disable the CUDA and AMDGPU backends:
93+
You could then set the environment variable `CMAKE_ARGS` (scikit-build-core's CMake-args passthrough) to configure the build. `build.py` reads it, layers on the toolchain options it manages, and exports it back. For instance, to disable the CUDA and AMDGPU backends:
9494

9595
```
9696
export CMAKE_ARGS="-DQD_WITH_CUDA=OFF -DQD_WITH_AMDGPU=OFF"
@@ -102,7 +102,7 @@ To direct `cmake` where to look at for some dependencies, for example `LLVM`, yo
102102
# using an env var
103103
export LLVM_DIR="/path/to/llvm/"
104104
# or with a cmake option
105-
export QUADRANTS_CMAKE_ARGS="$QUADRANTS_CMAKE_ARGS -DLLVM_ROOT=/path/to/llvm"
105+
export CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ROOT=/path/to/llvm"
106106
```
107107

108108
### Building with the AMD GPU backend (Linux)
@@ -114,22 +114,6 @@ The AMD GPU backend is Linux-only (it is force-disabled on macOS and Windows) an
114114
CMAKE_ARGS="-DQD_WITH_AMDGPU=ON -DQD_WITH_CUDA=OFF" pip install --no-build-isolation -e . -v
115115
```
116116

117-
## Advanced usage
118-
119-
### CI Convention about compilers/LLVM
120-
121-
Quadrants comprises at least three important parts:
122-
123-
1. `quadrants` host runtime: Made with a mix of Python and C++. The C++ core is compiled using the OS default C/C++ compiler.
124-
2. `quadrants` device runtime (bitcode): C++ code compiled using `clang++` from the distribution/OS. Using `clang++` is required as it has to support the same targets as `LLVM`.
125-
3. `LLVM` libraries used by host runtime: statically or dynamically linked, used to lower the kernel's final IR to machine code on the host. The CI uses an LLVM version compiled from source.
126-
127-
### Building LLVM for debugging it
128-
129-
Sometimes, it could be useful to have a `LLVM` version that allows to print intermediate passes or with debug symbols to find out where and why LLVM fails (for example, when Instruction Selection fails). To do so you would have to build LLVM by yourself. If so, you should take some inspiration from our [CI pipeline to build LLVM](https://github.com/Genesis-Embodied-AI/quadrants-sdk-builds/blob/main/.github/workflows/llvm-ci.yml) to tweak a little bit to your liking (and not enable/disable options that would create discrepancies).
130-
131-
You can then use `LLVM_DIR` to point to the `LLVM` build directory.
132-
133117
## CI checks
134118

135119
Pull requests are validated by several CI jobs. Most run automatically; a failing check blocks merge.
@@ -227,3 +211,19 @@ quadrants/program/legacy_stream.cpp 42 -42
227211
The `0` in the LoC column for the two new files reflects that both files did not exist before this PR (their pre-PR code-line count is 0). The `42 -42` row for `legacy_stream.cpp` is a fully-deleted file: 42 code lines existed before this PR and all 42 were removed.
228212

229213
This check is delayed by 30 minutes, to avoid running repeatedly if multiple commits pushed with a short delay between each.
214+
215+
## Advanced
216+
217+
### CI Convention about compilers/LLVM
218+
219+
Quadrants comprises at least three important parts:
220+
221+
1. `quadrants` host runtime: Made with a mix of Python and C++. The C++ core is compiled using the OS default C/C++ compiler.
222+
2. `quadrants` device runtime (bitcode): C++ code compiled using `clang++` from the distribution/OS. Using `clang++` is required as it has to support the same targets as `LLVM`.
223+
3. `LLVM` libraries used by host runtime: statically or dynamically linked, used to lower the kernel's final IR to machine code on the host. The CI uses an LLVM version compiled from source.
224+
225+
### Building LLVM for debugging it
226+
227+
Sometimes, it could be useful to have a `LLVM` version that allows to print intermediate passes or with debug symbols to find out where and why LLVM fails (for example, when Instruction Selection fails). To do so you would have to build LLVM by yourself. If so, you should take some inspiration from our [CI pipeline to build LLVM](https://github.com/Genesis-Embodied-AI/quadrants-sdk-builds/blob/main/.github/workflows/llvm-ci.yml) to tweak a little bit to your liking (and not enable/disable options that would create discrepancies).
228+
229+
You can then use `LLVM_DIR` to point to the `LLVM` build directory.

0 commit comments

Comments
 (0)