DkSDKBuildHost

When cross-compiling sometimes you need tools like source code generators that must run on your build machine (the host ABI), not the target ABI.

You can accomplish this by using commands like the following:

FetchContent_Declare(json-generator
  # Add fields that describe where the source code is.
  # It must be a CMake project.
)
DkSDKBuildHost_Add(
  FETCHCONTENT_NAME json-generator
  INSTALL_DIR_VARIABLE host_install_dir
)
set(JsonGenerator_DIR "${host_install_dir}")
find_package(JsonGenerator)

To access the host ABI libraries and executables you have two choices:

  1. Just like the example above, you can set the <packageName>_DIR variable and then use find_package(packageName). The requirement is that your host ABI project used both:

  2. You can use either or both of:

    and then using the INSTALL_DIR_VARIABLE (ex. ${host_install_dir)) set:

DkSDKBuildHost_Add

Adds a CMake project containing libraries and executables that will be built for the host ABI.

DkSDKBuildHost_Add(
  FETCHCONTENT_NAME <name>
  [FETCHCONTENT_AVAILABLE]
  INSTALL_DIR_VARIABLE <variable>
  BUILD_TARGET_VARIABLE <target>
  [SOURCE_SUBDIR <subdir>]
  [PATCH_COMMAND ...]
  [CONFIGURE_C_FROM_OCAML]
  [DEPENDS ...]
  [BUILD_BYPRODUCTS <file1> ... <fileN>]
  [CMAKE_ARGS ...]
)

The default pattern that DkSDKBuildHost_Add uses for building (which can be customized) is:

  1. Fetch the content from FETCHCONTENT_NAME with FetchContent_Populate(name) command to fetch the source code. The source code can be a local directory using FetchContent_Populate(name URL dir) or FetchContent_Populate(name SOURCE_DIR dir).

  2. Use ExternalProject_Add(PATCH_COMMAND ...) to spawn a separate cmake process with automatically inferred CMake variables for the host ABI. That will build and install the fetched content in the host ABI.

Using the FETCHCONTENT_AVAILABLE flag also builds the target ABI in a different location from the host ABI. The flag modifies the first "Fetch the content" step. It uses FetchContent_MakeAvailable(name) to fetch the content, which means that if the content includes a CMakeLists.txt, that build script will be run. That will build and install the fetched content in the target ABI.

CMake Variables in Host and Target ABI

Use the CMAKE_ARGS option to set CMake variables for the host ABI. Normal CMake variables (ex. set(VARIABLE_X_Y_Z TRUE)) and CACHE CMake variables (ex. set(VARIABLE_A_B_C 123 CACHE STRING "")) are not visible during the host ABI build. For example:

include(DkSDKBuildHost)
DkSDKBuildHost_Add(
   FETCHCONTENT_NAME xxxxxx
   # Variables visible to Host ABI builds
   CMAKE_ARGS
     -D "BUILD_TESTING=OFF"
     -D "CMAKE_CXX_STANDARD=14"
     -D "CMAKE_CXX_STANDARD_REQUIRED=YES"
   # ...
)

If FETCHCONTENT_AVAILABLE is on, you can set normal CMake variables to influence the target ABI build. CMAKE_ARGS are not visible during the target ABI build. For example:

# Variables visible to Target ABI builds
set(BUILD_TESTING OFF)
set(WITH_OPENSSL ON)
set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB TRUE)

include(DkSDKBuildHost) DkSDKBuildHost_Add( FETCHCONTENT_NAME xxxxxx FETCHCONTENT_AVAILABLE # ... )

Options

FETCHCONTENT_NAME <name>

The source for the host ABI project. It must have previously been declared with FetchContent_Declare(name)

Subsequent FetchContent_MakeAvailable(name) for <name> will succeed but do nothing. Use FETCHCONTENT_AVAILABLE if you need the target ABI build.

FETCHCONTENT_AVAILABLE

The toplevel CMakeLists.txt in the content's source directory will be run, if any, in the target ABI using FetchContent_MakeAvailable(name).

INSTALL_DIR_VARIABLE <variable>

The install directory for the host ABI project will be placed in the <variable> variable.

BUILD_TARGET_VARIABLE <target>

The name of the build target will be placed in the <target> variable. The name of the build target is <name>-host_Proj where <name> is what was specified in FETCHCONTENT_NAME.

The target, when run, will build the host ABI project. The build target is not any of the executables or libraries generated by the host ABI project. Use the INSTALL_DIR_VARIABLE instead to find and import the generated executables and libraries.

SOURCE_SUBDIR <subdir>

By default the CMakeLists.txt is expected in the top source directory. With SOURCE_SUBDIR you can change which directory contains the CMakeLists.txt. It should be a relative path from the top source directory.

The functionality and syntax are the same as ExternalProject_Add(SOURCE_SUBDIR ...)

PATCH_COMMAND ...

Patches the host ABI project. The original FetchContent directory is never modified; instead, a copy of the FetchContent directory is made, and then it is patched. That means you can re-use the FetchContent directory for other purposes.

You may use <SOURCE_DIR> and <SOURCE_SUBDIR> as placeholders.

The syntax is the same as ExternalProject_Add(PATCH_COMMAND ...)

CONFIGURE_C_FROM_OCAML

By default the command makes an intelligent guess what the host C and C++ compiler are. With CONFIGURE_C_FROM_OCAML the host C compiler that was detected for OCaml during the project(name LANGUAGES C OCamlDune) command is used. If you only need a C compiler then CONFIGURE_C_FROM_OCAML is a good flag to use. However, OCamlDune does not use C++ so no host C++ compiler will be configured in the host ABI project. Do not use CONFIGURE_C_FROM_OCAML if you need C++.

DEPENDS ...

Targets that, when changed, should trigger a rebuild of the host ABI project.

Do not use add_dependencies() to add target dependencies to the host ABI project.

The functionality and syntax are the same as ExternalProject_Add(DEPENDS ...)

CMAKE_ARGS

Extra CMake arguments to pass to the host ABI project during its configure phase.

Some CMake arguments are supplied automatically. Any arguments you give can override the following supplied defaults:

  • CMAKE_INSTALL_PREFIX

  • CMAKE_C_COMPILER if CONFIGURE_C_FROM_OCAML enabled

  • CMAKE_C_FLAGS if CONFIGURE_C_FROM_OCAML enabled

The functionality and syntax are the same as ExternalProject_Add(CMAKE_ARGS ...)

These CMAKE_ARGS do not override CMake normal variables of the same name.

BUILD_BYPRODUCTS <file1> ... <fileN>

Make the outputs known to Ninja and some (not all) build tools. If you rely on an output file, you should (strong recommendation!) set the byproducts. Use <INSTALL_DIR> as a short-hand for the installation directory.

The functionality and syntax are the same as ExternalProject_Add(BUILD_BYPRODUCTS ...)