1# Halide and CMake 2 3This is a comprehensive guide to the three main usage stories of the Halide 4CMake build. 5 61. Compiling or packaging Halide from source. 72. Building Halide programs using the official CMake package. 83. Contributing to Halide and updating the build files. 9 10The following sections cover each in detail. 11 12## Table of Contents 13 14- [Getting started](#getting-started) 15 - [Installing CMake](#installing-cmake) 16 - [Installing dependencies](#installing-dependencies) 17- [Building Halide with CMake](#building-halide-with-cmake) 18 - [Basic build](#basic-build) 19 - [Build options](#build-options) 20 - [Find module options](#find-module-options) 21- [Using Halide from your CMake build](#using-halide-from-your-cmake-build) 22 - [A basic CMake project](#a-basic-cmake-project) 23 - [JIT mode](#jit-mode) 24 - [AOT mode](#aot-mode) 25 - [Autoschedulers](#autoschedulers) 26 - [RunGenMain](#rungenmain) 27 - [Halide package documentation](#halide-package-documentation) 28 - [Components](#components) 29 - [Variables](#variables) 30 - [Imported targets](#imported-targets) 31 - [Functions](#functions) 32 - [`add_halide_library`](#add_halide_library) 33- [Contributing CMake code to Halide](#contributing-cmake-code-to-halide) 34 - [General guidelines and best practices](#general-guidelines-and-best-practices) 35 - [Prohibited commands list](#prohibited-commands-list) 36 - [Prohibited variables list](#prohibited-variables-list) 37 - [Adding tests](#adding-tests) 38 - [Adding apps](#adding-apps) 39 40# Getting started 41 42This section covers installing a recent version of CMake and the correct 43dependencies for building and using Halide. If you have not used CMake before, 44we strongly suggest reading through the [CMake documentation][cmake-docs] first. 45 46## Installing CMake 47 48Halide requires at least version 3.16, which was released in November 2019. 49Fortunately, getting a recent version of CMake couldn't be easier, and there are 50multiple good options on any system to do so. Generally, one should always have 51the most recent version of CMake installed system-wide. CMake is committed to 52backwards compatibility and even the most recent release can build projects over 53a decade old. 54 55### Cross-platform 56 57The Python package manager `pip3` has the newest version of CMake at all times. 58This might be the most convenient method since Python 3 is an optional 59dependency for Halide, anyway. 60 61``` 62$ pip3 install --upgrade cmake 63``` 64 65See the [PyPI website][pypi-cmake] for more details. 66 67### Windows 68 69On Windows, there are three primary methods for installing an up-to-date CMake: 70 711. If you have Visual Studio 2019 installed, you can get CMake 3.17 through the 72 Visual Studio installer. This is the recommended way of getting CMake if you 73 are able to use Visual Studio 2019. See Microsoft's 74 [documentation][vs2019-cmake-docs] for more details. 752. If you use [Chocolatey][chocolatey], its [CMake package][choco-cmake] is kept 76 up to date. It should be as simple as `choco install cmake`. 773. Otherwise, you should install CMake from [Kitware's website][cmake-download]. 78 79### macOS 80 81On macOS, the [Homebrew][homebrew] [CMake package][brew-cmake] is kept up to 82date. Simply run: 83 84``` 85$ brew update 86$ brew install cmake 87``` 88 89to install the newest version of CMake. If your environment prevents you from 90installing Homebrew, the binary release on [Kitware's website][cmake-download] 91is also a viable option. 92 93### Ubuntu Linux 94 95There are a few good ways to install a modern CMake on Ubuntu: 96 971. If you're on Ubuntu Linux 20.04 (focal), then simply running 98 `sudo apt install cmake` will get you CMake 3.16. 992. If you are on an older Ubuntu release or would like to use the newest CMake, 100 try installing via the snap store: `snap install cmake`. Be sure you do not 101 already have `cmake` installed via APT. The snap package automatically stays 102 up to date. 1033. For older versions of Debian, Ubuntu, Mint, and derivatives, Kitware provides 104 an [APT repository][cmake-apt] with up-to-date releases. Note that this is 105 still useful for Ubuntu 20.04 because it will remain up to date. 1064. If all else fails, you might need to build CMake from source (eg. on old 107 Ubuntu versions running on ARM). In that case, follow the directions posted 108 on [Kitware's website][cmake-from-source]. 109 110For other Linux distributions, check with your distribution's package manager or 111use pip as detailed above. Snap packages might also be available. 112 113**Note:** On WSL 1, the snap service is not available; in this case, prefer to 114use the APT repository. On WSL 2, all methods are available. 115 116## Installing dependencies 117 118We generally recommend using a package manager to fetch Halide's dependencies. 119Except where noted, we recommend using [vcpkg][vcpkg] on Windows, 120[Homebrew][homebrew] on macOS, and APT on Ubuntu 20.04 LTS. 121 122Only LLVM and Clang are _absolutely_ required to build Halide. Halide always 123supports three LLVM versions: the current major version, the previous major 124version, and trunk. The LLVM and Clang versions must match exactly. For most 125users, we recommend using a binary release of LLVM rather than building it 126yourself. 127 128However, to run all of the tests and apps, an extended set is needed. This 129includes [lld][lld], [Python 3][python], [libpng][libpng], [libjpeg][libjpeg], 130[Doxygen][doxygen], [OpenBLAS][openblas], [ATLAS][atlas], and [Eigen3][eigen]. 131While not required to build any part of Halide, we find that [Ninja][ninja] is 132the best backend build tool across all platforms. 133 134Note that CMake has many special variables for overriding the locations of 135packages and executables. A partial list can be found in the 136["find module options"](#find-module-options) section below, and more can be 137found in the documentation for the CMake [find_package][find_package] command. 138Normally, you should prefer to make sure your environment is set up so that 139CMake can find dependencies automatically. For instance, if you want CMake to 140use a particular version of Python, create a [virtual environment][venv] and 141activate it _before_ configuring Halide. 142 143### Windows 144 145We assume you have vcpkg installed at `D:\vcpkg`. Follow the instructions in the 146[vcpkg README][vcpkg] to install. Start by installing LLVM. 147 148``` 149D:\vcpkg> .\vcpkg install llvm[target-all,enable-assertions,clang-tools-extra]:x64-windows 150D:\vcpkg> .\vcpkg install llvm[target-all,enable-assertions,clang-tools-extra]:x86-windows 151``` 152 153This will also install Clang and LLD. The `enable-assertions` option is not 154strictly necessary but will make debugging during development much smoother. 155These builds will take a long time and a lot of disk space. After they are 156built, it is safe to delete the intermediate build files and caches in 157`D:\vcpkg\buildtrees` and `%APPDATA%\local\vcpkg`. 158 159Then install the other libraries: 160 161``` 162D:\vcpkg> .\vcpkg install libpng:x64-windows libjpeg-turbo:x64-windows openblas:x64-windows eigen3:x64-windows 163D:\vcpkg> .\vcpkg install libpng:x86-windows libjpeg-turbo:x86-windows openblas:x86-windows eigen3:x86-windows 164``` 165 166To build the documentation, you will need to install [Doxygen][doxygen]. This 167can be done either through [Chocolatey][choco-doxygen] or from the [Doxygen 168website][doxygen-download]. 169 170``` 171> choco install doxygen 172``` 173 174To build the Python bindings, you will need to install Python 3. This should be 175done by running the official installer from the [Python website][python]. Be 176sure to download the debugging symbols through the installer. This will require 177using the "Advanced Installation" workflow. Although it is not strictly 178necessary, it is convenient to install Python system-wide on Windows (ie. 179`C:\Program Files`). This makes it easy for CMake to find without needing to 180manually set the `PATH`. 181 182Once Python is installed, you can install the Python module dependencies either 183globally or in a [virtual environment][venv] by running 184 185``` 186> pip3 install -r .\python_bindings\requirements.txt 187``` 188 189from the root of the repository. 190 191If you would like to use [Ninja][ninja], note that it is installed alongside 192CMake when using the Visual Studio 2019 installer. Alternatively, you can 193install via [Chocolatey][choco-ninja] or place the [pre-built 194binary][ninja-download] from their website in the PATH. 195 196``` 197> choco install ninja 198``` 199 200### macOS 201 202On macOS, it is possible to install all dependencies via [Homebrew][homebrew]: 203 204``` 205$ brew install llvm libpng libjpeg python@3.8 openblas doxygen ninja 206``` 207 208The `llvm` package includes `clang`, `clang-format`, and `lld`, too. Don't 209forget to install the Python module dependencies: 210 211``` 212$ pip3 install -r python_bindings/requirements.txt 213``` 214 215### Ubuntu 216 217Finally, on Ubuntu 20.04 LTS, you should install the following packages (this 218includes the Python module dependencies): 219 220``` 221dev@ubuntu:~$ sudo apt install \ 222 clang-tools lld llvm-dev libclang-dev liblld-10-dev \ 223 libpng-dev libjpeg-dev libgl-dev \ 224 python3-dev python3-numpy python3-scipy python3-imageio python3-pybind11 \ 225 libopenblas-dev libeigen3-dev libatlas-base-dev \ 226 doxygen ninja-build 227``` 228 229# Building Halide with CMake 230 231## Basic build 232 233These instructions assume that your working directory is the Halide repo root. 234 235### Windows 236 237If you plan to use the Ninja generator, be sure to be in the developer command 238prompt corresponding to your intended environment. Note that whatever your 239intended target system (x86, x64, or arm), you must use the 64-bit _host tools_ 240because the 32-bit tools run out of memory during the linking step with LLVM. 241More information is available from [Microsoft's documentation][msvc-cmd]. 242 243You should either open the correct Developer Command Prompt directly or run the 244[`vcvarsall.bat`][vcvarsall] script with the correct argument, ie. one of the 245following: 246 247``` 248D:\> "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 249D:\> "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64_x86 250D:\> "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64_arm 251``` 252 253Then, assuming that vcpkg is installed to `D:\vcpkg`, simply run: 254 255``` 256> cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=D:\vcpkg\scripts\buildsystems\vcpkg.cmake -S . -B build 257> cmake --build .\build 258``` 259 260Valid values of [`CMAKE_BUILD_TYPE`][cmake_build_type] are `Debug`, 261`RelWithDebInfo`, `MinSizeRel`, and `Release`. When using a single-configuration 262generator (like Ninja) you must specify a build type when configuring Halide (or 263any other CMake project). 264 265Otherwise, if you wish to create a Visual Studio based build system, you can 266configure with: 267 268``` 269> cmake -G "Visual Studio 16 2019" -Thost=x64 -A x64 ^ 270 -DCMAKE_TOOLCHAIN_FILE=D:\vcpkg\scripts\buildsystems\vcpkg.cmake ^ 271 -S . -B build 272> cmake --build .\build --config Release -j %NUMBER_OF_PROCESSORS% 273``` 274 275Because the Visual Studio generator is a _multi-config generator_, you don't set 276`CMAKE_BUILD_TYPE` at configure-time, but instead pass the configuration to the 277build (and test/install) commands with the `--config` flag. More documentation 278is available in the [CMake User Interaction Guide][cmake-user-interaction]. 279 280The process is similar for 32-bit: 281 282``` 283> cmake -G "Visual Studio 16 2019" -Thost=x64 -A Win32 ^ 284 -DCMAKE_TOOLCHAIN_FILE=D:\vcpkg\scripts\buildsystems\vcpkg.cmake ^ 285 -S . -B build 286> cmake --build .\build --config Release -j %NUMBER_OF_PROCESSORS% 287``` 288 289In both cases, the `-Thost=x64` flag ensures that the correct host tools are 290used. 291 292**Note:** due to limitations in MSBuild, incremental builds using the VS 293generators will not detect changes to headers in the `src/runtime` folder. We 294recommend using Ninja for day-to-day development and use Visual Studio only if 295you need it for packaging. 296 297### macOS and Linux 298 299The instructions here are straightforward. Assuming your environment is set up 300correctly, just run: 301 302``` 303dev@host:~/Halide$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S . -B build 304dev@host:~/Halide$ cmake --build ./build 305``` 306 307If you omit `-G Ninja`, a Makefile-based generator will likely be used instead. 308In either case, [`CMAKE_BUILD_TYPE`][cmake_build_type] must be set to one of the 309standard types: `Debug`, `RelWithDebInfo`, `MinSizeRel`, or `Release`. 310 311## Installing 312 313Once built, Halide will need to be installed somewhere before using it in a 314separate project. On any platform, this means running the 315[`cmake --install`][cmake-install] command in one of two ways. For a 316single-configuration generator (like Ninja), run either: 317 318``` 319dev@host:~/Halide$ cmake --install ./build --prefix /path/to/Halide-install 320> cmake --install .\build --prefix X:\path\to\Halide-install 321``` 322 323For a multi-configuration generator (like Visual Studio) run: 324 325``` 326dev@host:~/Halide$ cmake --install ./build --prefix /path/to/Halide-install --config Release 327> cmake --install .\build --prefix X:\path\to\Halide-install --config Release 328``` 329 330Of course, make sure that you build the corresponding config before attempting 331to install it. 332 333## Build options 334 335Halide reads and understands several options that can configure the build. The 336following are the most consequential and control how Halide is actually 337compiled. 338 339| Option | Default | Description | 340| ---------------------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------- | 341| [`BUILD_SHARED_LIBS`][build_shared_libs] | `ON` | Standard CMake variable that chooses whether to build as a static or shared library. | 342| `Halide_BUNDLE_LLVM` | `OFF` | When building Halide as a static library, unpack the LLVM static libraries and add those objects to libHalide.a. | 343| `Halide_SHARED_LLVM` | `OFF` | Link to the shared version of LLVM. Not available on Windows. | 344| `Halide_ENABLE_RTTI` | _inherited from LLVM_ | Enable RTTI when building Halide. Recommended to be set to `ON` | 345| `Halide_ENABLE_EXCEPTIONS` | `ON` | Enable exceptions when building Halide | 346| `Halide_USE_CODEMODEL_LARGE` | `OFF` | Use the Large LLVM codemodel | 347| `Halide_TARGET` | _empty_ | The default target triple to use for `add_halide_library` (and the generator tests, by extension) | 348 349The following options are only available when building Halide directly, ie. not 350through the [`add_subdirectory`][add_subdirectory] or 351[`FetchContent`][fetchcontent] mechanisms. They control whether non-essential 352targets (like tests and documentation) are built. 353 354| Option | Default | Description | 355| ---------------------- | -------------------- | ---------------------------------------------------------------------------------------- | 356| `WITH_TESTS` | `ON` | Enable building unit and integration tests | 357| `WITH_APPS` | `ON` | Enable testing sample applications (run `ctest -L apps` to actually build and test them) | 358| `WITH_PYTHON_BINDINGS` | `ON` if Python found | Enable building Python 3.x bindings | 359| `WITH_DOCS` | `OFF` | Enable building the documentation via Doxygen | 360| `WITH_UTILS` | `ON` | Enable building various utilities including the trace visualizer | 361| `WITH_TUTORIALS` | `ON` | Enable building the tutorials | 362 363The following options control whether to build certain test subsets. They only 364apply when `WITH_TESTS=ON`: 365 366| Option | Default | Description | 367| ------------------------- | ------- | --------------------------------- | 368| `WITH_TEST_AUTO_SCHEDULE` | `ON` | enable the auto-scheduling tests | 369| `WITH_TEST_CORRECTNESS` | `ON` | enable the correctness tests | 370| `WITH_TEST_ERROR` | `ON` | enable the expected-error tests | 371| `WITH_TEST_WARNING` | `ON` | enable the expected-warning tests | 372| `WITH_TEST_PERFORMANCE` | `ON` | enable performance testing | 373| `WITH_TEST_OPENGL` | `OFF` | enable the OpenGL tests | 374| `WITH_TEST_GENERATOR` | `ON` | enable the AOT generator tests | 375 376The following options enable/disable various LLVM backends (they correspond to 377LLVM component names): 378 379| Option | Default | Description | 380| -------------------- | -------------------- | -------------------------------------------------------- | 381| `TARGET_AARCH64` | `ON`, _if available_ | Enable the AArch64 backend | 382| `TARGET_AMDGPU` | `ON`, _if available_ | Enable the AMD GPU backend | 383| `TARGET_ARM` | `ON`, _if available_ | Enable the ARM backend | 384| `TARGET_HEXAGON` | `ON`, _if available_ | Enable the Hexagon backend | 385| `TARGET_MIPS` | `ON`, _if available_ | Enable the MIPS backend | 386| `TARGET_NVPTX` | `ON`, _if available_ | Enable the NVidia PTX backend | 387| `TARGET_POWERPC` | `ON`, _if available_ | Enable the PowerPC backend | 388| `TARGET_RISCV` | `ON`, _if available_ | Enable the RISC V backend | 389| `TARGET_WEBASSEMBLY` | `ON`, _if available_ | Enable the WebAssembly backend. Only valid for LLVM 11+. | 390| `TARGET_X86` | `ON`, _if available_ | Enable the x86 (and x86_64) backend | 391 392The following options enable/disable various Halide-specific backends: 393 394| Option | Default | Description | 395| --------------------- | ------- | -------------------------------------- | 396| `TARGET_OPENCL` | `ON` | Enable the OpenCL-C backend | 397| `TARGET_OPENGL` | `ON` | Enable the OpenGL/GLSL backend | 398| `TARGET_METAL` | `ON` | Enable the Metal backend | 399| `TARGET_D3D12COMPUTE` | `ON` | Enable the Direct3D 12 Compute backend | 400 401The following options are WebAssembly-specific. They only apply when 402`TARGET_WEBASSEMBLY=ON`: 403 404| Option | Default | Description | 405| ----------------- | ------- | ---------------------------------------------------------- | 406| `WITH_WABT` | `ON` | Include WABT Interpreter for WASM testing | 407| `WITH_WASM_SHELL` | `ON` | Download a wasm shell (e.g. d8) for testing AOT wasm code. | 408 409### Find module options 410 411Halide uses the following find modules to search for certain dependencies. These 412modules accept certain variables containing hints for the search process. Before 413setting any of these variables, closely study the [`find_package`][find_package] 414documentation. 415 416All of these variables should be set at the CMake command line via the `-D` 417flag. 418 419First, Halide expects to find LLVM and Clang through the `CONFIG` mode of 420`find_package`. You can tell Halide where to find these dependencies by setting 421the corresponding `_DIR` variables: 422 423| Variable | Description | 424| ----------- | ---------------------------------------------------- | 425| `LLVM_DIR` | Path to the directory containing `LLVMConfig.cmake` | 426| `Clang_DIR` | Path to the directory containing `ClangConfig.cmake` | 427 428When using CMake 3.18 or above, some of Halide's tests will search for CUDA 429using the [`FindCUDAToolkit`][findcudatoolkit] module. If it doesn't find your 430CUDA installation automatically, you can point it to it by setting: 431 432| Variable | Description | 433| ------------------ | ------------------------------------------------- | 434| `CUDAToolkit_ROOT` | Path to the directory containing `bin/nvcc[.exe]` | 435| `CUDA_PATH` | _Environment_ variable, same as above. | 436 437If the CMake version is lower than 3.18, the deprecated [`FindCUDA`][findcuda] 438module will be used instead. It reads the variable `CUDA_TOOLKIT_ROOT_DIR` 439instead of `CUDAToolkit_ROOT` above. 440 441When targeting OpenGL, the [`FindOpenGL`][findopengl] and [`FindX11`][findx11] 442modules will be used to link AOT generated binaries. These modules can be 443overridden by setting the following variables: 444 445| Variable | Description | 446| ----------------------- | -------------------------------- | 447| `OPENGL_egl_LIBRARY` | Path to the EGL library. | 448| `OPENGL_glu_LIBRARY` | Path to the GLU library. | 449| `OPENGL_glx_LIBRARY` | Path to the GLVND GLX library. | 450| `OPENGL_opengl_LIBRARY` | Path to the GLVND OpenGL library | 451| `OPENGL_gl_LIBRARY` | Path to the OpenGL library. | 452 453The OpenGL paths will need to be set if you intend to use OpenGL with X11 on 454macOS. 455 456Halide also searches for `libpng` and `libjpeg-turbo` through the 457[`FindPNG`][findpng] and [`FindJPEG`][findjpeg] modules, respectively. They can 458be overridden by setting the following variables. 459 460| Variable | Description | 461| ------------------- | -------------------------------------------------- | 462| `PNG_LIBRARIES` | Paths to the libraries to link against to use PNG. | 463| `PNG_INCLUDE_DIRS` | Path to `png.h`, etc. | 464| `JPEG_LIBRARIES` | Paths to the libraries needed to use JPEG. | 465| `JPEG_INCLUDE_DIRS` | Paths to `jpeglib.h`, etc. | 466 467When `WITH_DOCS` is set to `ON`, Halide searches for Doxygen using the 468[`FindDoxygen`][finddoxygen] module. It can be overridden by setting the 469following variable. 470 471| Variable | Description | 472| -------------------- | ------------------------------- | 473| `DOXYGEN_EXECUTABLE` | Path to the Doxygen executable. | 474 475When compiling for an OpenCL target, Halide uses the [`FindOpenCL`][findopencl] 476target to locate the libraries and include paths. These can be overridden by 477setting the following variables: 478 479| Variable | Description | 480| --------------------- | ----------------------------------------------------- | 481| `OpenCL_LIBRARIES` | Paths to the libraries to link against to use OpenCL. | 482| `OpenCL_INCLUDE_DIRS` | Include directories for OpenCL. | 483 484Lastly, Halide searches for Python 3 using the [`FindPython3`][findpython3] 485module, _not_ the deprecated `FindPythonInterp` and `FindPythonLibs` modules, 486like other projects you might have encountered. You can select which Python 487installation to use by setting the following variable. 488 489| Variable | Description | 490| ------------------ | ----------------------------------------------------- | 491| `Python3_ROOT_DIR` | Define the root directory of a Python 3 installation. | 492 493# Using Halide from your CMake build 494 495This section assumes some basic familiarity with CMake but tries to be explicit 496in all its examples. To learn more about CMake, consult the 497[documentation][cmake-docs] and engage with the community on the [CMake 498Discourse][cmake-discourse]. 499 500Note: previous releases bundled a `halide.cmake` module that was meant to be 501[`include()`][include]-ed into your project. This has been removed. Please 502upgrade to the new package config module. 503 504## A basic CMake project 505 506There are two main ways to use Halide in your application: as a **JIT compiler** 507for dynamic pipelines or an **ahead-of-time (AOT) compiler** for static 508pipelines. CMake provides robust support for both use cases. 509 510No matter how you intend to use Halide, you will need some basic CMake 511boilerplate. 512 513```cmake 514cmake_minimum_required(VERSION 3.16) 515project(HalideExample) 516 517set(CMAKE_CXX_STANDARD 11) # or newer 518set(CMAKE_CXX_STANDARD_REQUIRED YES) 519set(CMAKE_CXX_EXTENSIONS NO) 520 521find_package(Halide REQUIRED) 522``` 523 524The [`cmake_minimum_required`][cmake_minimum_required] command is required to be 525the first command executed in a CMake program. It disables all of the deprecated 526behavior ("policies" in CMake lingo) from earlier versions. The 527[`project`][project] command sets the name of the project (and has arguments for 528versioning, language support, etc.) and is required by CMake to be called 529immediately after setting the minimum version. 530 531The next three variables set the project-wide C++ standard. The first, 532[`CMAKE_CXX_STANDARD`][cmake_cxx_standard], simply sets the standard version. 533Halide requires at least C++11. The second, 534[`CMAKE_CXX_STANDARD_REQUIRED`][cmake_cxx_standard_required], tells CMake to 535fail if the compiler cannot provide the requested standard version. Lastly, 536[`CMAKE_CXX_EXTENSIONS`][cmake_cxx_extensions] tells CMake to disable 537vendor-specific extensions to C++. This is not necessary to simply use Halide, 538but we require it when authoring new code in the Halide repo. 539 540Finally, we use [`find_package`][find_package] to locate Halide on your system. 541If Halide is not globally installed, you will need to add the root of the Halide 542installation directory to [`CMAKE_MODULE_PATH`][cmake_module_path] at the CMake 543command line. 544 545``` 546dev@ubuntu:~/myproj$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_MODULE_PATH="/path/to/Halide-install" -S . -B build 547``` 548 549## JIT mode 550 551To use Halide in JIT mode (like the [tutorials][halide-tutorials] do, for 552example), you can simply link to `Halide::Halide`. 553 554```cmake 555# ... same project setup as before ... 556add_executable(my_halide_app main.cpp) 557target_link_libraries(my_halide_app PRIVATE Halide::Halide) 558``` 559 560Then `Halide.h` will be available to your code and everything should just work. 561That's it! 562 563## AOT mode 564 565Using Halide in AOT mode is more complicated so we'll walk through it step by 566step. Note that this only applies to Halide generators, so it might be useful to 567re-read the [tutorial][halide-generator-tutorial] on generators. Assume (like in 568the tutorial) that you have a source file named `my_generators.cpp` and that in 569it you have generator classes `MyFirstGenerator` and `MySecondGenerator` with 570registered names `my_first_generator` and `my_second_generator` respectively. 571 572Then the first step is to add a **generator executable** to your build: 573 574```cmake 575# ... same project setup as before ... 576add_executable(my_generators my_generators.cpp) 577target_link_libraries(my_generators PRIVATE Halide::Generator) 578``` 579 580Using the generator executable, we can add a Halide library corresponding to 581`MyFirstGenerator`. 582 583```cmake 584# ... continuing from above 585add_halide_library(my_first_generator FROM my_generators) 586``` 587 588This will create a static library target in CMake that corresponds to the output 589of running your generator. The second generator in the file requires generator 590parameters to be passed to it. These are also easy to handle: 591 592```cmake 593# ... continuing from above 594add_halide_library(my_second_generator FROM my_generators 595 PARAMS parallel=false scale=3.0 rotation=ccw output.type=uint16) 596``` 597 598Adding multiple configurations is easy, too: 599 600```cmake 601# ... continuing from above 602add_halide_library(my_second_generator_2 FROM my_generators 603 GENERATOR my_second_generator 604 PARAMS scale=9.0 rotation=ccw output.type=float32) 605 606add_halide_library(my_second_generator_3 FROM my_generators 607 GENERATOR my_second_generator 608 PARAMS parallel=false output.type=float64) 609``` 610 611Here, we had to specify which generator to use (`my_second_generator`) since it 612uses the target name by default. The functions in these libraries will be named 613after the target names, `my_second_generator_2` and `my_second_generator_3`, by 614default, but it is possible to control this via the `FUNCTION_NAME` parameter. 615 616Each one of these targets, `<GEN>`, carries an associated `<GEN>.runtime` 617target, which is also a static library containing the Halide runtime. It is 618transitively linked through `<GEN>` to targets that link to `<GEN>`. On an 619operating system like Linux, where weak linking is available, this is not an 620issue. However, on Windows, this can fail due to symbol redefinitions. In these 621cases, you must declare that two Halide libraries share a runtime, like so: 622 623```cmake 624# ... updating above 625add_halide_library(my_second_generator_2 FROM my_generators 626 GENERATOR my_second_generator 627 USE_RUNTIME my_first_generator.runtime 628 PARAMS scale=9.0 rotation=ccw output.type=float32) 629 630add_halide_library(my_second_generator_3 FROM my_generators 631 GENERATOR my_second_generator 632 USE_RUNTIME my_first_generator.runtime 633 PARAMS parallel=false output.type=float64) 634``` 635 636This will even work correctly when different combinations of targets are 637specified for each halide library. A "greatest common denominator" target will 638be chosen that is compatible with all of them (or the build will fail). 639 640### Autoschedulers 641 642When the autoschedulers are included in the release package, they are very 643simple to apply to your own generators. For example, we could update the 644definition of the `my_first_generator` library above to use the `Adams2019` 645autoscheduler: 646 647```cmake 648add_halide_library(my_second_generator FROM my_generators 649 AUTOSCHEDULER Halide::Adams2019 650 PARAMS auto_schedule=true) 651``` 652 653### RunGenMain 654 655Halide provides a generic driver for generators to be used during development 656for benchmarking and debugging. Suppose you have a generator executable called 657`my_gen` and a generator within called `my_filter`. Then you can pass a variable 658name to the `REGISTRATION` parameter of `add_halide_library` which will contain 659the name of a generated C++ source that should be linked to `Halide::RunGenMain` 660and `my_filter`. 661 662For example: 663 664```cmake 665add_halide_library(my_filter FROM my_gen 666 REGISTRATION filter_reg_cpp) 667add_executable(runner ${filter_reg_cpp}) 668target_link_libraries(runner PRIVATE my_filter Halide::RunGenMain) 669``` 670 671Then you can run, debug, and benchmark your generator through the `runner` 672executable. 673 674## Halide package documentation 675 676Halide provides a CMake _package configuration_ module. The intended way to use 677the CMake build is to run `find_package(Halide ...)` in your `CMakeLists.txt` 678file. Closely read the [`find_package` documentation][find_package] before 679proceeding. 680 681### Components 682 683The Halide package script understands a handful of optional components when 684loading the package. 685 686First, if you plan to use the Halide Image IO library, you will want to include 687the `png` and `jpeg` components when loading Halide. 688 689Second, Halide releases can contain a variety of configurations: static, shared, 690debug, release, etc. CMake handles Debug/Release configurations automatically, 691but generally only allows one type of library to be loaded. 692 693The package understands two components, `static` and `shared`, that specify 694which type of library you would like to load. For example, if you want to make 695sure that you link against shared Halide, you can write: 696 697```cmake 698find_package(Halide REQUIRED COMPONENTS shared) 699``` 700 701If the shared libraries are not available, this will result in a failure. 702 703If no component is specified, then the `Halide_SHARED_LIBS` variable is checked. 704If it is defined and set to true, then the shared libraries will be loaded or 705the package loading will fail. Similarly, if it is defined and set to false, the 706static libraries will be loaded. 707 708If no component is specified and `Halide_SHARED_LIBS` is _not_ defined, then the 709[`BUILD_SHARED_LIBS`][build_shared_libs] variable will be inspected. If it is 710**not defined** or **defined and set to true**, then it will attempt to load the 711shared libs and fall back to the static libs if they are not available. 712Similarly, if `BUILD_SHARED_LIBS` is **defined and set to false**, then it will 713try the static libs first then fall back to the shared libs. 714 715### Variables 716 717Variables that control package loading: 718 719| Variable | Description | 720| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 721| `Halide_SHARED_LIBS` | override `BUILD_SHARED_LIBS` when loading the Halide package via `find_package`. Has no effect when using Halide via `add_subdirectory` as a Git or `FetchContent` submodule. | 722 723Variables set by the package: 724 725| Variable | Description | 726| -------------------------- | ---------------------------------------------------------------- | 727| `Halide_VERSION` | The full version string of the loaded Halide package | 728| `Halide_VERSION_MAJOR` | The major version of the loaded Halide package | 729| `Halide_VERSION_MINOR` | The minor version of the loaded Halide package | 730| `Halide_VERSION_PATCH` | The patch version of the loaded Halide package | 731| `Halide_VERSION_TWEAK` | The tweak version of the loaded Halide package | 732| `Halide_HOST_TARGET` | The Halide target triple corresponding to "host" for this build. | 733| `Halide_ENABLE_EXCEPTIONS` | Whether Halide was compiled with exception support | 734| `Halide_ENABLE_RTTI` | Whether Halide was compiled with RTTI | 735 736### Imported targets 737 738Halide defines the following targets that are available to users: 739 740| Imported target | Description | 741| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | 742| `Halide::Halide` | this is the JIT-mode library to use when using Halide from C++. | 743| `Halide::Generator` | this is the target to use when defining a generator executable. It supplies a `main()` function. | 744| `Halide::Runtime` | adds include paths to the Halide runtime headers | 745| `Halide::Tools` | adds include paths to the Halide tools, including the benchmarking utility. | 746| `Halide::ImageIO` | adds include paths to the Halide image IO utility and sets up dependencies to PNG / JPEG if they are available. | 747| `Halide::RunGenMain` | used with the `REGISTRATION` parameter of `add_halide_library` to create simple runners and benchmarking tools for Halide libraries. | 748 749The following targets are not guaranteed to be available: 750 751| Imported target | Description | 752| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | 753| `Halide::Python` | this is a Python 3 module that can be referenced as `$<TARGET_FILE:Halide::Python>` when setting up Python tests or the like from CMake. | 754| `Halide::Adams19` | the Adams et.al. 2019 autoscheduler (no GPU support) | 755| `Halide::Li18` | the Li et.al. 2018 gradient autoscheduler (limited GPU support) | 756 757### Functions 758 759Currently, only one function is defined: 760 761#### `add_halide_library` 762 763This is the main function for managing generators in AOT compilation. The full 764signature follows: 765 766``` 767add_halide_library(<target> FROM <generator-target> 768 [GENERATOR generator-name] 769 [FUNCTION_NAME function-name] 770 [USE_RUNTIME hl-target] 771 [PARAMS param1 [param2 ...]] 772 [TARGETS target1 [target2 ...]] 773 [FEATURES feature1 [feature2 ...]] 774 [PLUGINS plugin1 [plugin2 ...]] 775 [AUTOSCHEDULER scheduler-name] 776 [GRADIENT_DESCENT] 777 [C_BACKEND] 778 [REGISTRATION OUTVAR] 779 [<extra-output> OUTVAR]) 780 781extra-output = ASSEMBLY | BITCODE | COMPILER_LOG | CPP_STUB 782 | FEATURIZATION | LLVM_ASSEMBLY | PYTHON_EXTENSION 783 | PYTORCH_WRAPPER | SCHEDULE | STMT | STMT_HTML 784``` 785 786This function creates a called `<target>` corresponding to running the 787`<generator-target>` (an executable target which links to `Halide::Generator`) 788one time, using command line arguments derived from the other parameters. 789 790The arguments `GENERATOR` and `FUNCTION_NAME` default to `<target>`. They 791correspond to the `-g` and `-f` command line flags, respectively. 792 793If `USE_RUNTIME` is not specified, this function will create another target 794called `<target>.runtime` which corresponds to running the generator with `-r` 795and a compatible list of targets. This runtime target is an INTERFACE dependency 796of `<target>`. If multiple runtime targets need to be linked together, setting 797`USE_RUNTIME` to another Halide library, `<target2>` will prevent the generation 798of `<target>.runtime` and instead use `<target2>.runtime`. 799 800Parameters can be passed to a generator via the `PARAMS` argument. Parameters 801should be space-separated. Similarly, `TARGETS` is a space-separated list of 802targets for which to generate code in a single function. They must all share the 803same platform/bits/os triple (eg. `arm-32-linux`). Features that are in common 804among all targets, including device libraries (like `cuda`) should go in 805`FEATURES`. 806 807Every element of `TARGETS` must begin with the same `arch-bits-os` triple. This 808function understands two _meta-triples_, `host` and `cmake`. The meta-triple 809`host` is equal to the `arch-bits-os` triple used to compile Halide along with 810all of the supported instruction set extensions. On platforms that support 811running both 32 and 64-bit programs, this will not necessarily equal the 812platform the compiler is running on or that CMake is targeting. 813 814The meta-triple `cmake` is equal to the `arch-bits-os` of the current CMake 815target. This is useful if you want to make sure you are not unintentionally 816cross-compiling, which would result in an [`IMPORTED` target][imported-target] 817being created. When `TARGETS` is empty and the `host` target would not 818cross-compile, then `host` will be used. Otherwise, `cmake` will be used and an 819author warning will be issued. 820 821To set the default autoscheduler, set the `AUTOSCHEDULER` argument to a target 822named like `Namespace::Scheduler`, for example `Halide::Adams19`. This will set 823the `-s` flag on the generator command line to `Scheduler` and add the target to 824the list of plugins. Additional plugins can be loaded by setting the `PLUGINS` 825argument. If the argument to `AUTOSCHEDULER` does not contain `::` or it does 826not name a target, it will be passed to the `-s` flag verbatim. 827 828If `GRADIENT_DESCENT` is set, then the module will be built suitably for 829gradient descent calculation in TensorFlow or PyTorch. See 830`Generator::build_gradient_module()` for more documentation. This corresponds to 831passing `-d 1` at the generator command line. 832 833If the `C_BACKEND` option is set, this command will invoke the configured C++ 834compiler on a generated source. Note that a `<target>.runtime` target is _not_ 835created in this case, and the `USE_RUNTIME` option is ignored. Other options 836work as expected. 837 838If `REGISTRATION` is set, the path to the generated `.registration.cpp` file 839will be set in `OUTVAR`. This can be used to generate a runner for a Halide 840library that is useful for benchmarking and testing, as documented above. This 841is equivalent to setting `-e registration` at the generator command line. 842 843Lastly, each of the `extra-output` arguments directly correspond to an extra 844output (via `-e`) from the generator. The value `OUTVAR` names a variable into 845which a path (relative to 846[`CMAKE_CURRENT_BINARY_DIR`][cmake_current_binary_dir]) to the extra file will 847be written. 848 849## Cross compiling 850 851Cross-compiling in CMake can be tricky, since CMake doesn't easily support 852compiling for both the host platform and the cross-platform within the same 853build. Unfortunately, Halide generator executables are just about always 854designed to run on the host platform. Each project will be set up differently 855and have different requirements, but here are some suggestions for effective use 856of CMake in these scenarios. 857 858### Use a super-build 859 860A CMake super-build consists of breaking down a project into sub-projects that 861are isolated by [toolchain][cmake-toolchains]. The basic structure is to have an 862outermost project that only coordinates the sub-builds via the 863[`ExternalProject`][externalproject] module. 864 865One would then use Halide to build a generator executable in one self-contained 866project, then export that target to be used in a separate project. The second 867project would be configured with the target [toolchain][cmake-toolchains] and 868would call `add_halide_library` with no `TARGETS` option and set `FROM` equal to 869the name of the imported generator executable. Obviously, this is a significant 870increase in complexity over a typical CMake project. 871 872### Use `ExternalProject` directly 873 874A lighter weight alternative to the above is to use 875[`ExternalProject`][externalproject] directly in your parent build. Configure 876the parent build with the target [toolchain][cmake-toolchains], and configure 877the inner project to use the host toolchain. Then, manually create an 878[`IMPORTED` target][imported-executable] for your generator executable and call 879`add_halide_library` as described above. 880 881The main drawback of this approach is that creating accurate `IMPORTED` targets 882is difficult since predicting the names and locations of your binaries across 883all possible platform and CMake project generators is difficult. In particular, 884it is hard to predict executable extensions in cross-OS builds. 885 886### Use an emulator or run on device 887 888The [`CMAKE_CROSSCOMPILING_EMULATOR`][cmake_crosscompiling_emulator] variable 889allows one to specify a command _prefix_ to run a target-system binary on the 890host machine. One could set this to a custom shell script that uploads the 891generator executable, runs it on the device and copies back the results. 892 893### Bypass CMake 894 895The previous two options ensure that the targets generated by 896`add_halide_library` will be _normal_ static libraries. This approach does not 897use [`ExternalProject`][externalproject], but instead produces `IMPORTED` 898targets. The main drawback of `IMPORTED` targets is that they are considered 899second-class in CMake. In particular, they cannot be installed with the typical 900[`install(TARGETS)` command][install-targets]. Instead, they must be installed 901using [`install(FILES)`][install-files] and the 902[`$<TARGET_FILE:tgt>`][target-file] generator expression. 903 904# Contributing CMake code to Halide 905 906When contributing new CMake code to Halide, keep in mind that the minimum 907version is 3.16. Therefore, it is possible (and indeed required) to use modern 908CMake best practices. 909 910Like any large and complex system with a dedication to preserving backwards 911compatibility, CMake is difficult to learn and full of traps. While not 912comprehensive, the following serves as a guide for writing quality CMake code 913and outlines the code quality expectations we have as they apply to CMake. 914 915## General guidelines and best practices 916 917The following are some common mistakes that lead to subtly broken builds. 918 919- **Reading the build directory.** While setting up the build, the build 920 directory should be considered _write only_. Using the build directory as a 921 read/write temporary directory is acceptable as long as all temp files are 922 cleaned up by the end of configuration. 923- **Not using [generator expressions][cmake-genex].** Declarative is better than 924 imperative and this is no exception. Conditionally adding to a target property 925 can leak unwanted details about the build environment into packages. Some 926 information is not accurate or available except via generator expressions, eg. 927 the build configuration. 928- **Using the wrong variable.** `CMAKE_SOURCE_DIR` doesn't always point to the 929 Halide source root. When someone uses Halide via 930 [`FetchContent`][fetchcontent], it will point to _their_ source root instead. 931 The correct variable is [`Halide_SOURCE_DIR`][project-name_source_dir]. If you 932 want to know if the compiler is MSVC, check it directly with the 933 [`MSVC`][msvc] variable; don't use [`WIN32`][win32]. That will be wrong when 934 compiling with clang on Windows. In most cases, however, a generator 935 expression will be more appropriate. 936- **Using directory properties.** Directory properties have vexing behavior and 937 are essentially deprecated from CMake 3.0+. Propagating target properties is 938 the way of the future. 939- **Using the wrong visibility.** Target properties can be `PRIVATE`, 940 `INTERFACE`, or both (aka `PUBLIC`). Pick the most conservative one for each 941 scenario. Refer to the [transitive usage requirements][cmake-propagation] docs 942 for more information. 943 944### Prohibited commands list 945 946As mentioned above, using directory properties is brittle and they are therefore 947_not allowed_. The following functions may not appear in any new CMake code. 948 949| Command | Alternative | 950| ----------------------------------- | -------------------------------------------------------------------------------------------------- | 951| `add_compile_definitions` | Use [`target_compile_definitions`][target_compile_definitions] | 952| `add_compile_options` | Use [`target_compile_options`][target_compile_options] | 953| `add_definitions` | Use [`target_compile_definitions`][target_compile_definitions] | 954| `add_link_options` | Use [`target_link_options`][target_link_options], but prefer not to use either | 955| `get_directory_property` | Use cache variables or target properties | 956| `get_property(... DIRECTORY)` | Use cache variables or target properties | 957| `include_directories` | Use [`target_include_directories`][target_include_directories] | 958| `link_directories` | Use [`target_link_libraries`][target_link_libraries] | 959| `link_libraries` | Use [`target_link_libraries`][target_link_libraries] | 960| `remove_definitions` | [Generator expressions][cmake-genex] in [`target_compile_definitions`][target_compile_definitions] | 961| `set_directory_properties` | Use cache variables or target properties | 962| `set_property(... DIRECTORY)` | Use cache variables or target properties | 963| `target_link_libraries(target lib)` | Use [`target_link_libraries`][target_link_libraries] _with a visibility specifier_ (eg. `PRIVATE`) | 964 965As an example, it was once common practice to write code similar to this: 966 967```cmake 968# WRONG: do not do this 969include_directories(include) 970add_library(my_lib source1.cpp ..) 971``` 972 973However, this has two major pitfalls. First, it applies to _all_ targets created 974in that directory, even those before the call to `include_directories` and those 975created in [`include()`][include]-ed CMake files. As CMake files get larger and 976more complex, this behavior gets harder to pinpoint. This is particularly vexing 977when using the `link_libraries` or `add_defintions` commands. Second, this form 978does not provide a way to _propagate_ the include directory to consumers of 979`my_lib`. The correct way to do this is: 980 981```cmake 982# CORRECT 983add_library(my_lib source1.cpp ...) 984target_include_directories(my_lib PUBLIC $<BUILD_INTERFACE:include>) 985``` 986 987This is better in many ways. It only affects the target in question. It 988propagates the include path to the targets linking to it (via `PUBLIC`). It also 989does not incorrectly export the host-filesystem-specific include path when 990installing or packaging the target (via `$<BUILD_INTERFACE>`). 991 992If common properties need to be grouped together, use an INTERFACE target 993(better) or write a function (worse). There are also several functions that are 994disallowed for other reasons: 995 996| Command | Reason | Alternative | 997| ------------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | 998| `aux_source_directory` | Interacts poorly with incremental builds and Git | List source files explicitly | 999| `build_command` | CTest internal function | Use CTest build-and-test mode via [`CMAKE_CTEST_COMMAND`][cmake_ctest_command] | 1000| `cmake_host_system_information` | Usually misleading information. | Inspect [toolchain][cmake-toolchains] variables and use generator expressions. | 1001| `cmake_policy(... OLD)` | OLD policies are deprecated by definition. | Instead, fix the code to work with the new policy. | 1002| `create_test_sourcelist` | We use our own unit testing solution | See the [adding tests](#adding-tests) section. | 1003| `define_property` | Adds unnecessary complexity | Use a cache variable. Exceptions under special circumstances. | 1004| `enable_language` | Halide is C/C++ only | [`FindCUDAToolkit`][findcudatoolkit] or [`FindCUDA`][findcuda], appropriately guarded. | 1005| `file(GLOB ...)` | Interacts poorly with incremental builds and Git | List source files explicitly. Allowed if not globbing for source files. | 1006| `fltk_wrap_ui` | Halide does not use FLTK | None | 1007| `include_external_msproject` | Halide must remain portable | Write a CMake package config file or find module. | 1008| `include_guard` | Use of recursive inclusion is not allowed | Write (recursive) functions. | 1009| `include_regular_expression` | Changes default dependency checking behavior | None | 1010| `load_cache` | Superseded by [`FetchContent`][fetchcontent]/[`ExternalProject`][externalproject] | Use aforementioned modules | 1011| `macro` | CMake macros are not hygienic and are therefore error-prone | Use functions instead. | 1012| `site_name` | Privacy: do not want leak host name information | Provide a cache variable, generate a unique name. | 1013| `variable_watch` | Debugging helper | None. Not needed in production. | 1014 1015Lastly, do not introduce any dependencies via [`find_package`][find_package] 1016without broader approval. Confine dependencies to the `dependencies/` subtree. 1017 1018### Prohibited variables list 1019 1020Any variables that are specific to languages that are not enabled should, of 1021course, be avoided. But of greater concern are variables that are easy to misuse 1022or should not be overridden for our end-users. The following (non-exhaustive) 1023list of variables shall not be used in code merged into master. 1024 1025| Variable | Reason | Alternative | 1026| ------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------- | 1027| `CMAKE_ROOT` | Code smell | Rely on `find_package` search options; include `HINTS` if necessary | 1028| `CMAKE_DEBUG_TARGET_PROPERTIES` | Debugging helper | None | 1029| `CMAKE_FIND_DEBUG_MODE` | Debugging helper | None | 1030| `CMAKE_RULE_MESSAGES` | Debugging helper | None | 1031| `CMAKE_VERBOSE_MAKEFILE` | Debugging helper | None | 1032| `CMAKE_BACKWARDS_COMPATIBILITY` | Deprecated | None | 1033| `CMAKE_BUILD_TOOL` | Deprecated | `${CMAKE_COMMAND} --build` or [`CMAKE_MAKE_PROGRAM`][cmake_make_program] (but see below) | 1034| `CMAKE_CACHEFILE_DIR` | Deprecated | [`CMAKE_BINARY_DIR`][cmake_binary_dir], but see below | 1035| `CMAKE_CFG_INTDIR` | Deprecated | `$<CONFIG>`, `$<TARGET_FILE:..>`, target resolution of [`add_custom_command`][add_custom_command], etc. | 1036| `CMAKE_CL_64` | Deprecated | [`CMAKE_SIZEOF_VOID_P`][cmake_sizeof_void_p] | 1037| `CMAKE_COMPILER_IS_*` | Deprecated | [`CMAKE_<LANG>_COMPILER_ID`][cmake_lang_compiler_id] | 1038| `CMAKE_HOME_DIRECTORY` | Deprecated | [`CMAKE_SOURCE_DIR`][cmake_source_dir], but see below | 1039| `CMAKE_DIRECTORY_LABELS` | Directory property | None | 1040| `CMAKE_BUILD_TYPE` | Only applies to single-config generators. | `$<CONFIG>` | 1041| `CMAKE_*_FLAGS*` (w/o `_INIT`) | User-only | Write a [toolchain][cmake-toolchains] file with the corresponding `_INIT` variable | 1042| `CMAKE_COLOR_MAKEFILE` | User-only | None | 1043| `CMAKE_ERROR_DEPRECATED` | User-only | None | 1044| `CMAKE_CONFIGURATION_TYPES` | We only support the four standard build types | None | 1045 1046Of course feel free to insert debugging helpers _while developing_ but please 1047remove them before review. Finally, the following variables are allowed, but 1048their use must be motivated: 1049 1050| Variable | Reason | Alternative | 1051| ---------------------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------- | 1052| [`CMAKE_SOURCE_DIR`][cmake_source_dir] | Points to global source root, not Halide's. | [`Halide_SOURCE_DIR`][project-name_source_dir] or [`PROJECT_SOURCE_DIR`][project_source_dir] | 1053| [`CMAKE_BINARY_DIR`][cmake_binary_dir] | Points to global build root, not Halide's | [`Halide_BINARY_DIR`][project-name_binary_dir] or [`PROJECT_BINARY_DIR`][project_binary_dir] | 1054| [`CMAKE_MAKE_PROGRAM`][cmake_make_program] | CMake abstracts over differences in the build tool. | Prefer CTest's build and test mode or CMake's `--build` mode | 1055| [`CMAKE_CROSSCOMPILING`][cmake_crosscompiling] | Often misleading. | Inspect relevant variables directly, eg. [`CMAKE_SYSTEM_NAME`][cmake_system_name] | 1056| [`BUILD_SHARED_LIBS`][build_shared_libs] | Could override user setting | None, but be careful to restore value when overriding for a dependency | 1057 1058Any use of these functions and variables will block a PR. 1059 1060## Adding tests 1061 1062When adding a file to any of the folders under `test`, be aware that CI expects 1063that every `.c` and `.cpp` appears in the `CMakeLists.txt` file _on its own 1064line_, possibly as a comment. This is to avoid globbing and also to ensure that 1065added files are not missed. 1066 1067For most test types, it should be as simple as adding to the existing lists, 1068which must remain in alphabetical order. Generator tests are trickier, but 1069following the existing examples is a safe way to go. 1070 1071## Adding apps 1072 1073If you're contributing a new app to Halide: great! Thank you! There are a few 1074guidelines you should follow when writing a new app. 1075 1076- Write the app as if it were a top-level project. You should call 1077 `find_package(Halide)` and set the C++ version to 11. 1078- Call [`enable_testing()`][enable_testing] and add a small test that runs the 1079 app. 1080- Don't assume your app will have access to a GPU. Write your schedules to be 1081 robust to varying buildbot hardware. 1082- Don't assume your app will be run on a specific OS, architecture, or bitness. 1083 Write your apps to be robust (ideally efficient) on all supported platforms. 1084- If you rely on any additional packages, don't include them as `REQUIRED`, 1085 instead test to see if their targets are available and, if not, call 1086 `return()` before creating any targets. In this case, print a 1087 `message(STATUS "[SKIP] ...")`, too. 1088- Look at the existing apps for examples. 1089- Test your app with ctest before opening a PR. Apps are built as part of the 1090 test, rather than the main build. 1091 1092[add_custom_command]: 1093 https://cmake.org/cmake/help/latest/command/add_custom_command.html 1094[add_library]: https://cmake.org/cmake/help/latest/command/add_library.html 1095[add_subdirectory]: 1096 https://cmake.org/cmake/help/latest/command/add_subdirectory.html 1097[atlas]: http://math-atlas.sourceforge.net/ 1098[brew-cmake]: https://formulae.brew.sh/cask/cmake#default 1099[build_shared_libs]: 1100 https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html 1101[choco-cmake]: https://chocolatey.org/packages/cmake/ 1102[choco-doxygen]: https://chocolatey.org/packages/doxygen.install 1103[choco-ninja]: https://chocolatey.org/packages/ninja 1104[chocolatey]: https://chocolatey.org/ 1105[cmake-apt]: https://apt.kitware.com/ 1106[cmake-discourse]: https://discourse.cmake.org/ 1107[cmake-docs]: https://cmake.org/cmake/help/latest/ 1108[cmake-download]: https://cmake.org/download/ 1109[cmake-from-source]: https://cmake.org/install/ 1110[cmake-genex]: 1111 https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html 1112[cmake-install]: 1113 https://cmake.org/cmake/help/latest/manual/cmake.1.html#install-a-project 1114[cmake-propagation]: 1115 https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#transitive-usage-requirements 1116[cmake-toolchains]: 1117 https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html 1118[cmake-user-interaction]: 1119 https://cmake.org/cmake/help/latest/guide/user-interaction/index.html#setting-build-variables 1120[cmake_binary_dir]: 1121 https://cmake.org/cmake/help/latest/variable/CMAKE_BINARY_DIR.html 1122[cmake_build_type]: 1123 https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html 1124[cmake_crosscompiling]: 1125 https://cmake.org/cmake/help/latest/variable/CMAKE_CROSSCOMPILING.html 1126[cmake_crosscompiling_emulator]: 1127 https://cmake.org/cmake/help/latest/variable/CMAKE_CROSSCOMPILING_EMULATOR.html 1128[cmake_ctest_command]: 1129 https://cmake.org/cmake/help/latest/variable/CMAKE_CTEST_COMMAND.html 1130[cmake_current_binary_dir]: 1131 https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_BINARY_DIR.html 1132[cmake_cxx_extensions]: 1133 https://cmake.org/cmake/help/latest/variable/CMAKE_CXX_EXTENSIONS.html 1134[cmake_cxx_standard]: 1135 https://cmake.org/cmake/help/latest/variable/CMAKE_CXX_STANDARD.html 1136[cmake_cxx_standard_required]: 1137 https://cmake.org/cmake/help/latest/variable/CMAKE_CXX_STANDARD_REQUIRED.html 1138[cmake_lang_compiler_id]: 1139 https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html 1140[cmake_make_program]: 1141 https://cmake.org/cmake/help/latest/variable/CMAKE_MAKE_PROGRAM.html 1142[cmake_minimum_required]: 1143 https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html 1144[cmake_module_path]: 1145 https://cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html 1146[cmake_sizeof_void_p]: 1147 https://cmake.org/cmake/help/latest/variable/CMAKE_SIZEOF_VOID_P.html 1148[cmake_source_dir]: 1149 https://cmake.org/cmake/help/latest/variable/CMAKE_SOURCE_DIR.html 1150[cmake_system_name]: 1151 https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_NAME.html 1152[doxygen-download]: https://www.doxygen.nl/download.html 1153[doxygen]: https://www.doxygen.nl/index.html 1154[eigen]: http://eigen.tuxfamily.org/index.php?title=Main_Page 1155[enable_testing]: 1156 https://cmake.org/cmake/help/latest/command/enable_testing.html 1157[externalproject]: 1158 https://cmake.org/cmake/help/latest/module/ExternalProject.html 1159[fetchcontent]: https://cmake.org/cmake/help/latest/module/FetchContent.html 1160[find_package]: https://cmake.org/cmake/help/latest/command/find_package.html 1161[findcuda]: https://cmake.org/cmake/help/latest/module/FindCUDA.html 1162[findcudatoolkit]: 1163 https://cmake.org/cmake/help/latest/module/FindCUDAToolkit.html 1164[finddoxygen]: https://cmake.org/cmake/help/latest/module/FindDoxygen.html 1165[findjpeg]: https://cmake.org/cmake/help/latest/module/FindJPEG.html 1166[findopencl]: https://cmake.org/cmake/help/latest/module/FindOpenCL.html 1167[findopengl]: https://cmake.org/cmake/help/latest/module/FindOpenGL.html 1168[findpng]: https://cmake.org/cmake/help/latest/module/FindPNG.html 1169[findpython3]: https://cmake.org/cmake/help/latest/module/FindPython3.html 1170[findx11]: https://cmake.org/cmake/help/latest/module/FindX11.html 1171[halide-generator-tutorial]: 1172 https://halide-lang.org/tutorials/tutorial_lesson_15_generators.html 1173[halide-tutorials]: https://halide-lang.org/tutorials/tutorial_introduction.html 1174[homebrew]: https://brew.sh 1175[imported-executable]: 1176 https://cmake.org/cmake/help/latest/command/add_executable.html#imported-executables 1177[imported-target]: 1178 https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#imported-targets 1179[include]: https://cmake.org/cmake/help/latest/command/include.html 1180[install-files]: https://cmake.org/cmake/help/latest/command/install.html#files 1181[install-targets]: 1182 https://cmake.org/cmake/help/latest/command/install.html#targets 1183[libjpeg]: https://www.libjpeg-turbo.org/ 1184[libpng]: http://www.libpng.org/pub/png/libpng.html 1185[lld]: https://lld.llvm.org/ 1186[msvc]: https://cmake.org/cmake/help/latest/variable/MSVC.html 1187[msvc-cmd]: 1188 https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=vs-2019 1189[ninja-download]: https://github.com/ninja-build/ninja/releases 1190[ninja]: https://ninja-build.org/ 1191[openblas]: https://www.openblas.net/ 1192[project]: https://cmake.org/cmake/help/latest/command/project.html 1193[project-name_binary_dir]: 1194 https://cmake.org/cmake/help/latest/variable/PROJECT-NAME_BINARY_DIR.html 1195[project-name_source_dir]: 1196 https://cmake.org/cmake/help/latest/variable/PROJECT-NAME_SOURCE_DIR.html 1197[project_source_dir]: 1198 https://cmake.org/cmake/help/latest/variable/PROJECT_SOURCE_DIR.html 1199[project_binary_dir]: 1200 https://cmake.org/cmake/help/latest/variable/PROJECT_BINARY_DIR.html 1201[pypi-cmake]: https://pypi.org/project/cmake/ 1202[python]: https://www.python.org/downloads/ 1203[target-file]: 1204 https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#target-dependent-queries 1205[target_compile_definitions]: 1206 https://cmake.org/cmake/help/latest/command/target_compile_definitions.html 1207[target_compile_options]: 1208 https://cmake.org/cmake/help/latest/command/target_compile_options.html 1209[target_include_directories]: 1210 https://cmake.org/cmake/help/latest/command/target_include_directories.html 1211[target_link_libraries]: 1212 https://cmake.org/cmake/help/latest/command/target_link_libraries.html 1213[target_link_options]: 1214 https://cmake.org/cmake/help/latest/command/target_link_options.html 1215[vcpkg]: https://github.com/Microsoft/vcpkg 1216[vcvarsall]: 1217 https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=vs-2019#vcvarsall-syntax 1218[venv]: https://docs.python.org/3/tutorial/venv.html 1219[vs2019-cmake-docs]: 1220 https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=vs-2019 1221[win32]: https://cmake.org/cmake/help/latest/variable/WIN32.html 1222