BinaryTarget

Operations to fully create and configure a C++ binary target. It greatly simplifies the most common process of creating an executable or library, by wrapping calls to CMake functions in higher-level functions. However, for more complex cases, you will need to use CMake's native commands. It requires CMake 3.20 or newer.

Synopsis

binary_target(CREATE <target-name> <STATIC|SHARED|HEADER|EXEC>)
binary_target(CONFIGURE_SETTINGS <target-name> [...])
binary_target(ADD_SOURCES <target-name> [...])
binary_target(ADD_PRECOMPILED_HEADER <target-name> HEADER_FILE <file-path>)
binary_target(ADD_INCLUDE_DIRECTORIES <target-name> INCLUDE_DIRECTORIES [<dir-path>...])
binary_target(ADD_DEPENDENCIES <target-name> DEPENDENCIES [<target-name>...|<gen-expr>...])
binary_target(CREATE_FULLY <target-name> [...])

Usage

binary_target(CREATE <target-name> <STATIC|SHARED|HEADER|EXEC>)

Create a binary target named <target-name> and add it to the current CMake project, according to the specified binary type: STATIC, SHARED , HEADER, EXEC.

Example usage:

binary_target(CREATE "my_static_lib" STATIC)
binary_target(CREATE "my_shared_lib" SHARED)
binary_target(CONFIGURE_SETTINGS <target-name> [...])

Configure settings for an existing binary target:

binary_target(CONFIGURE_SETTINGS <target-name>
             COMPILE_FEATURES [<feature>...]
             COMPILE_DEFINITIONS [<definition>...]
             COMPILE_OPTIONS [<option>...]
             LINK_OPTIONS [<option>...])

This command updates compile and link settings of a previously created target <target-name> with PRIVATE visibility. The following configuration options are supported:

At the first call, the command sets the CXX_STANDARD property using the value of CMAKE_CXX_STANDARD, which must be defined. The target is also assigned to a default folder for improved IDE integration. All options are optional and may appear in any order. If a section is missing, it is simply ignored without warning.

This command is intended for targets that have been previously created using binary_target(CREATE).

Example usage:

binary_target(CREATE "my_shared_lib" SHARED)
binary_target(CONFIGURE_SETTINGS "my_shared_lib"
  COMPILE_FEATURES "cxx_std_20"
  COMPILE_DEFINITIONS "MY_DEFINE"
  COMPILE_OPTIONS "-Wall" "-Wextra"
  LINK_OPTIONS "-s"
)
binary_target(ADD_SOURCES <target-name> [...])

Add source and header files to an existing binary target:

binary_target(ADD_SOURCES <target-name>
             SOURCE_FILES [<file-path>...]
             PRIVATE_HEADER_FILES [<file-path>...]
             PUBLIC_HEADER_FILES [<file-path>...])

Assigns implementation and header files to the given binary target <target-name> with PRIVATE visibility:

  • SOURCE_FILES: A list of source files (e.g., .cpp, .c) typically located in the src/ directory.

  • PRIVATE_HEADER_FILES: A list of private headers (e.g., .h) typically located in the src/ directory.

  • PUBLIC_HEADER_FILES: A list of public headers, usually found in an include/ directory.

These files are added to the target with target_sources() to populate the SOURCES target property. The command also defines a logical grouping of source files in IDEs (e.g., Visual Studio) using source_group(), based on the project's source tree.

This command is intended for targets that have been previously created using binary_target(CREATE), and is typically used in conjunction with directory(COLLECT_SOURCES_BY_POLICY) to get the required files.

Example usage:

binary_target(CREATE "my_static_lib" STATIC)
binary_target(ADD_SOURCES "my_static_lib"
  SOURCE_FILES "src/main.cpp" "src/util.cpp" "src/source_1.cpp"
  PRIVATE_HEADER_FILES "src/util.h" "src/source_1.h"
  PUBLIC_HEADER_FILES "include/lib_1.h" "include/lib_2.h"
)

# Or with `directory(COLLECT_SOURCES_BY_POLICY)`
binary_target(CREATE "my_static_lib" STATIC)
directory(COLLECT_SOURCES_BY_POLICY
  PUBLIC_HEADERS_SEPARATED on "${CMAKE_SOURCE_DIR}/include/mylib"
  SRC_DIR "${CMAKE_SOURCE_DIR}/src"
  SRC_SOURCE_FILES sources
  PUBLIC_HEADER_DIR public_headers_dir
  PUBLIC_HEADER_FILES public_headers
  PRIVATE_HEADER_DIR private_headers_dir
  PRIVATE_HEADER_FILES private_headers
)
binary_target(ADD_SOURCES "my_static_lib"
  SOURCE_FILES "${sources}"
  PRIVATE_HEADER_FILES "${private_headers}"
  PUBLIC_HEADER_FILES "${public_headers}"
)
binary_target(ADD_PRECOMPILED_HEADER <target-name> HEADER_FILE <file-path>)

Add a precompiled header file (PCH) <file_path> to an existing binary target <target_name> with PRIVATE visibility. The file is added to the target with target_precompile_headers() to populate the PRECOMPILE_HEADERS target property.

This command is intended for targets that have been previously created using binary_target(CREATE).

Example usage:

binary_target(CREATE "my_static_lib" STATIC)
binary_target(ADD_PRECOMPILED_HEADER "my_static_lib"
  HEADER_FILE "src/header_pch.h"
)
binary_target(ADD_INCLUDE_DIRECTORIES <target-name> INCLUDE_DIRECTORIES [<dir-path>...])

Add include directories to an existing binary target <target_name> with PRIVATE visibility. The file is added to the target with target_include_directories() to populate the INCLUDE_DIRECTORIES target property.

This command is intended for targets that have been previously created using binary_target(CREATE), and is typically used in conjunction with directory(COLLECT_SOURCES_BY_POLICY) to get the required files.

Example usage:

binary_target(CREATE "my_static_lib" STATIC)
binary_target(ADD_INCLUDE_DIRECTORIES "my_static_lib"
  INCLUDE_DIRECTORIES "include"
)
binary_target(ADD_DEPENDENCIES <target-name> DEPENDENCIES [<target-name>...|<gen-expr>...])

Add dependencies to use when linking a given target <target-name>.

The DEPENDENCIES keyword lists the names of other targets or generator expressions to linke to <target-name>.

The behavior is equivalent to calling target_link_libraries().

Example usage:

# With target name
binary_target(CREATE "my_static_lib" STATIC)
binary_target(ADD_DEPENDENCIES "my_static_lib"
  DEPENDENCIES "dep_1" "dep_2"
)

# With generator expression
binary_target(CREATE "my_static_lib" STATIC)
binary_target(ADD_DEPENDENCIES "my_static_lib"
  DEPENDENCIES
    "$<BUILD_INTERFACE:dep_1;dep_2>"
    "$<INSTALL_INTERFACE:dep_1;dep_2>"
)
binary_target(CREATE_FULLY <target-name> [...])

Create a fully configured binary target.

binary_target(CREATE_FULLY <target-name>
              <STATIC|SHARED|HEADER|EXEC>
              [COMPILE_FEATURES <feature>...]
              [COMPILE_DEFINITIONS <definition>...]
              [COMPILE_OPTIONS <option>...]
              [LINK_OPTIONS <option>...]
              SOURCE_FILES [<file-path>...]
              PRIVATE_HEADER_FILES [<file-path>...]
              PUBLIC_HEADER_FILES [<file-path>...]
              [PRECOMPILED_HEADER_FILE <file-path>]
              INCLUDE_DIRECTORIES [<dir-path>...]
              [DEPENDENCIES [<target-name>...] ])

Create a fully configured binary target named <target-name> and add it to the current project. This command acts as a high-level wrapper that combines the behavior of other module sub-commands, including binary_target(CREATE), binary_target(CONFIGURE_SETTINGS), binary_target(ADD_SOURCES), binary_target(ADD_PRECOMPILED_HEADER), binary_target(ADD_INCLUDE_DIRECTORIES), and binary_target(ADD_DEPENDENCIES).

The second argument must specify the type of binary target to create: STATIC, SHARED, HEADER, or EXEC. Only one type may be given.

Additional parameters can be provided to configure compile options, precompiled headers, include directories, and target dependencies. Each of these keywords delegates internally to the corresponding BinaryTarget command. See their documentation for details. Example usage:

directory(COLLECT_SOURCES_BY_POLICY
  PUBLIC_HEADERS_SEPARATED on "${CMAKE_SOURCE_DIR}/include/mylib"
  SRC_DIR "${CMAKE_SOURCE_DIR}/src"
  SRC_SOURCE_FILES sources
  PUBLIC_HEADER_DIR public_headers_dir
  PUBLIC_HEADER_FILES public_headers
  PRIVATE_HEADER_DIR private_headers_dir
  PRIVATE_HEADER_FILES private_headers
)
binary_target(
  CREATE_FULLY "my_shared_lib"
  SHARED
  COMPILE_FEATURES "cxx_std_20"
  COMPILE_DEFINITIONS "MY_DEFINE"
  COMPILE_OPTIONS "-Wall" "-Wextra"
  LINK_OPTIONS "-s"
  SOURCE_FILES "${sources}"
  PRIVATE_HEADER_FILES "${private_headers}"
  PUBLIC_HEADER_FILES "${public_headers}"
  PRECOMPILED_HEADER_FILE "src/header_pch.h"
  INCLUDE_DIRECTORIES "$<$<BOOL:${private_headers_dir}>:${private_headers_dir}>" "${public_headers_dir}"
  DEPENDENCIES "dep_1" "dep_2"
)

Full example

This example shows how to call the module functions to create a complete binary.

binary_target(CREATE "my_shared_lib" SHARED)
binary_target(CONFIGURE_SETTINGS "my_shared_lib"
  COMPILE_FEATURES "cxx_std_20"
  COMPILE_DEFINITIONS "MY_DEFINE"
  COMPILE_OPTIONS "-Wall" "-Wextra"
  LINK_OPTIONS "-s"
)
directory(COLLECT_SOURCES_BY_POLICY
  PUBLIC_HEADERS_SEPARATED on "${CMAKE_SOURCE_DIR}/include/mylib"
  SRC_DIR "${CMAKE_SOURCE_DIR}/src"
  SRC_SOURCE_FILES sources
  PUBLIC_HEADER_DIR public_headers_dir
  PUBLIC_HEADER_FILES public_headers
  PRIVATE_HEADER_DIR private_headers_dir
  PRIVATE_HEADER_FILES private_headers
)
binary_target(ADD_SOURCES "my_shared_lib"
  SOURCE_FILES "${sources}"
  PRIVATE_HEADER_FILES "${private_headers}"
  PUBLIC_HEADER_FILES "${public_headers}"
)
binary_target(ADD_PRECOMPILED_HEADER "my_shared_lib"
  HEADER_FILE "src/header_pch.h"
)
binary_target(ADD_INCLUDE_DIRECTORIES "my_shared_lib"
  INCLUDE_DIRECTORIES "$<$<BOOL:${private_headers_dir}>:${private_headers_dir}>" "${public_headers_dir}"
)