Modules¶
JcmAllModules¶
When included, includes all of JCM’s CMake modules, excluding any Find Modules.
JcmSetupProject¶
Offers utilities to properly setup a CMake project for consumption as both a sub-project and a
binary package. Creates target component, COMPONENT, and defines macro
jcm_setup_project()
used to setup a CMake project.
jcm_setup_project¶
- jcm_setup_project¶
jcm_setup_project([PREFIX_NAME <project-prefix>])
Sets up a CMake project in the top-level CMakeLists.txt.
- This function will:
guard against misuse and malpractice, such as
PROJECT_NAME
being defined, the call-site is in the top-level CMakeLists.txt, preventing in-source builds, and ensuring project naming conventions.set variable
JCM_PROJECT_PREFIX_NAME
to the upper-case project name, orPREFIX_NAME
, if provided. This variable is used as the prefix name to subsequent macros, options, and variables.create options:
- ${JCM_PROJECT_PREFIX_NAME}_ENABLE_TESTS
Enables/disables building project tests for this specific project. Default:
BUILD_TESTING
- ${JCM_PROJECT_PREFIX_NAME}_ENABLE_DOCS
Enables/disables building project documentation for this specific project. Default: OFF
set default values for CMake variables controlling the build when the current project is the top-level project
CMAKE_BUILD_TYPE
CMAKE_EXPORT_COMPILE_COMMANDS
CMAKE_LINK_WHAT_YOU_USE
CMAKE_COLOR_DIAGNOSTICS
CMAKE_INSTALL_PREFIX
CMAKE_DEBUG_POSTFIX
CMAKE_OBJECT_PATH_MAX
(Windows)
set values for variables CMake uses to initialize target properties, only when the current project is top-level
CMAKE_INSTALL_RPATH
(runtime search path (RPATH) for shared object libraries)CMAKE_ARCHIVE_OUTPUT_DIRECTORY
CMAKE_LIBRARY_OUTPUT_DIRECTORY
CMAKE_RUNTIME_OUTPUT_DIRECTORY
CMAKE_<LANG>_STANDARD
CMAKE_<LANG>_STANDARD_REQUIRED
CMAKE_<LANG>_EXTENSIONS
CMAKE_<LANG>_VISIBILITY_PRESET
CMAKE_VISIBILITY_INLINES_HIDDEN
enable interprocedural optimization in Release mode
always enable testing so testing never fails, even if there are no tests, and includes CTest when ${JCM_PROJECT_PREFIX_NAME}_ENABLE_TESTS is set. The global property CTEST_TARGETS_ADDED is set to disable CTest from producing the often unused CDash targets until the CTest policy changes.
Parameters¶
Options¶
WITH_CTEST_TARGETS
When set, skips setting the global property CTEST_TARGETS_ADDED such that CTest creates targets for interoperability with CDash. These targets are commonly unused, so they’re disable by JCM by default. See CTest policy changes
One Value¶
PREFIX_NAME
Sets variable
JCM_PROJECT_PREFIX_NAME
, which is used as the prefix for variables, macros, options, etc. specific to this project.
Examples¶
jcm_setup_project()
jcm_setup_project(PREFIX_NAME STX)
JcmAddExecutable¶
jcm_add_executable¶
- jcm_add_executable¶
jcm_add_executable( [WITHOUT_CANONICAL_PROJECT_CHECK] [WITHOUT_FILE_NAMING_CHECK] [COMPONENT <component>] [NAME <name>] [OUT_TARGET <out-var>] [LIB_SOURCES <source>...] SOURCES <source>...)
Adds an executable target to the project, similar to CMake’s add_executable
, but with
enhancements. It allows creating both the executable and, optionally, an associated object or
interface library to allow better automated testing of the executable’s sources. This library
will have the same name as the executable, but with ‘-library’ appended (main -> main-library).
This function will:
ensure it’s called within a canonical source subdirectory, verify the naming conventions and locations of the input source files, and transform
SOURCES
andLIB_SOURCES
to normalized absolute paths.create an executable target with
add_executable()
, including an associated aliasoptionally create an object library, <target>-library, with an associated alias <PROJECT_NAME>::<EXPORT_NAME>-library (<PROJECT_NAME>::<EXPORT_NAME>) - both following JCM’s target naming conventions
optionally create an object library, <target>-library, with an associated alias <PROJECT_NAME>::<EXPORT_NAME>-library (<PROJECT_NAME>::<EXPORT_NAME>) - both following JCM’s target naming conventions
create header sets with
jcm_header_file_sets()
for both the main executable target, and the optional library target. PRIVATE header sets will be added to the executable using header files found inSOURCES
, while PUBLIC or INTERFACE header sets will be added to the object/interface library using header files found inLIB_SOURCES
. This is what sets the INCLUDE_DIRECTORIES properties.set target properties:
OUTPUT_NAME
EXPORT_NAME
COMPILE_OPTIONS
INCLUDE_DIRECTORIES
COMPONENT (custom property to JCM)
Parameters¶
Options¶
WITHOUT_CANONICAL_PROJECT_CHECK
When provided, will forgo the default check that the function is called within an executable source subdirectory, as defined by the Canonical Project Structure.
WITHOUT_FILE_NAMING_CHECK
When provided, will forgo the default check that provided header and source files conform to JCM’s file naming conventions
One Value¶
COMPONENT
Specifies the component that this executable represents. Used to set COMPONENT property and when naming the target.
NAME
Overrides the target name, output name, and exported name from those automatically created to conform to JCM’s naming conventions
OUT_TARGET
The variable named will be set to the created target’s name
Multi Value¶
LIB_SOURCES
Sources used to create the executable’s associated object/interface library. When provided, an object or interface library will be created, it will be linked against the executable, and its include directories will be set instead of the executable’s. An object library will be created when any of the file names of
LIB_SOURCES
matchJCM_SOURCE_REGEX
, while an interface library will be created otherwise (just header files).SOURCES
Sources used to create the executable
Examples¶
jcm_add_executable(SOURCES main.cpp)
target_link_libraries(example::example PRIVATE libthird::party)
# PROJECT_NAME is xml
# target will be xml::xml
jcm_add_executable(
OUT_TARGET target
SOURCES main.cpp
LIB_SOURCES xml.cpp)
jcm_add_test_executable(
NAME test_parser
SOURCES test_parser.cpp
LIBS ${target}-library Boost::ut)
# creates associated interface library, instead of object library
jcm_add_executable(
OUT_TARGET target
SOURCES main.cpp
LIB_SOURCES coffee.hpp)
JcmAddLibrary¶
jcm_add_library¶
- jcm_add_library¶
jcm_add_library( [WITHOUT_CANONICAL_PROJECT_CHECK] [WITHOUT_FILE_NAMING_CHECK] [COMPONENT <component>] [NAME <name>] [OUT_TARGET <out-var>] [TYPE <STATIC | SHARED | MODULE | INTERFACE | OBJECT>] <[INTERFACE_HEADERS <header>...] [PUBLIC_HEADERS <header>...] [PRIVATE_HEADERS <header>...] [SOURCES <source>...] >)
Adds a library target to the project, similar to CMake’s add_library, but with enhancements.
This function will:
ensure it’s called within a canonical source subdirectory, verify the naming conventions and locations of the input source files, and transform
SOURCES
to normalized, absolute pathscreate a library target with
add_library()
, including an associated alias (<PROJECT_NAME>::<EXPORT_NAME>) - both following JCM’s target naming conventionscreate PRIVATE, PUBLIC, and INTERFACE header sets with
jcm_header_file_sets()
using the respective *_HEADERS parameters. This is what sets the *INCLUDE_DIRECTORIES propertiesGenerate a header file, ${CMAKE_CURRENT_BINARY_DIR}/export_macros.hpp, with
generate_export_header()
create project options to control building the library shared. The precedence of the options increases with their specificity
- BUILD_SHARED_LIBS
global to entire build; used by almost all projects
- <JCM_PROJECT_PREFIX_NAME>_BUILD_SHARED_LIBS
specific to the project. Default:
BUILD_SHARED_LIBS
- <JCM_PROJECT_PREFIX_NAME>_<UPPERCASE_COMPONENT>_BUILD_SHARED
specific to component, if COMPONENT is provided. Default:
<JCM_PROJECT_PREFIX_NAME>_BUILD_SHARED_LIBS
set target properties:
OUTPUT_NAME
EXPORT_NAME
PREFIX
COMPILE_OPTIONS
INTERFACE_INCLUDE_DIRECTORIES
INCLUDE_DIRECTORIES
VERSION
SOVERSION
COMPONENT (custom property to JCM)
Parameters¶
Options¶
WITHOUT_CANONICAL_PROJECT_CHECK
When provided, will forgo the default check that the function is called within an executable source subdirectory, as defined by the Canonical Project Structure.
WITHOUT_FILE_NAMING_CHECK
When provided, will forgo the default check that provided header and source files conform to JCM’s file naming conventions
One Value¶
COMPONENT
Specifies the component that this executable represents. Used to set the target’s COMPONENT property, and when naming the target.
NAME
Overrides the target name, output name, and exported name from those automatically created to conform to JCM’s naming conventions
OUT_TARGET
The variable named will be set to the created target’s name
TYPE
Overrides the library type from the default value. When
SOURCES
are provided, the default is one of either STATIC or SHARED, dictated by the *_BUILD_SHARED_LIBS configuration options. Otherwise, the default is INTERFACE. When specified, this call will not create any of the *_BUILD_SHARED_LIBS options. Supported values: STATIC SHARED MODULE INTERFACE OBJECT.
Multi Value¶
INTERFACE_HEADERS
Header files required by consumers of this library, but not this library itself. Required when
TYPE
is INTERFACE.PUBLIC_HEADERS
Header files required by both consumers of this library and this library itself. Prohibited when
TYPE
is INTERFACE.PRIVATE_HEADERS
Header files required by this library itself, but not any consumers of this library. Prohibited when
TYPE
is INTERFACE.SOURCES
Sources used to create the library
Examples¶
jcm_add_library(PUBLIC_HEADERS engine.hpp SOURCES engine.cpp)
# PROJECT_NAME is car
# Target will be named car::libengine (query through OUT_TARGET)
# Shared options will be BUILD_SHARED_LIBS, CAR_BUILD_SHARED_LIBS, CAR_ENGINE_BUILD_SHARED
jcm_add_library(
COMPONENT engine
PUBLIC_HEADERS engine.hpp
PRIVATE_HEADERS crank.hpp
SOURCES engine.cpp crank.cpp)
jcm_add_executable(SOURCES main.cpp)
target_link_libraries(car::car PRIVATE car::libengine)
JcmAddTestExecutable¶
jcm_add_test_executable¶
- jcm_add_test_executable¶
jcm_add_test_executable( NAME <name> [TEST_NAME <test-name>] [LIBS <lib>...] SOURCES <source>...)
A convenience function to create an executable and add it as a test in one command, while also
setting target properties. This function has no affect if
${JCM_PROJECT_PREFIX_NAME}_ENABLE_TESTS
is not set.
This function will:
verify the input source files using
jcm_verify_target_sources()
, and use the cleaned sources produced by that function.create an executable with name
NAME
fromSOURCES
.register this executable as a test via CTest with name
TEST_NAME
, which defaults toNAME
, ifTEST_NAME
isn’t provided.creates a private header set
set target properties:
OUTPUT_NAME
COMPILE_OPTIONS
LINK_LIBRARIES
Parameters¶
One Value¶
NAME
Sets the target name and output name of the created executable. Used as the default test name if
TEST_NAME
is not provided.TEST_NAME
Sets the test name to be registered with CTest.
Multi Value¶
LIBS
Libraries to privately link against the created executable. Commonly the library that the created executable will test, and a testing framework.
SOURCES
Sources used to create the executable
Examples¶
jcm_add_test_executable(NAME my_test SOURCES my_test.cpp)
jcm_add_executable(
OUT_TARGET target
SOURCES main.cpp
LIB_SOURCES engine.cpp)
jcm_add_test_executable(
NAME test_engine
SOURCES test_engine.cpp
LIBS ${target}-library Boost::ut)
JcmSourceSubdirectories¶
jcm_source_subdirectories¶
- jcm_source_subdirectories¶
jcm_source_subdirectories( [WITH_TESTS_DIR] [WITH_DOCS_DIR] <[OUT_VAR <out-var>] [ADD_SUBDIRS] > [LIB_COMPONENTS <component>...] [EXEC_COMPONENTS <component>...])
Computes and optionally adds subdirectories following JGD’s project structure, which includes the
Canonical Project Structure, which pertains to source subdirectories. These canonical
subdirectories are provided by functions in JcmCanonicalStructure, while project directories are
provided by JCM_PROJECT_TESTS_DIR
and JCM_PROJECT_DOCS_DIR
from
JcmStandardDirs.
Executable and library subdirectories for non-components will be added first, if they exist. Then, source subdirectories for library and executable components will be added for the components specified, with errors if they don’t exist. Then, the standard tests and docs directory will be optionally added - see Options
This is a function, which prevents added subdirectories from populating variables in the calling list-file’s scope. Bubbling up variables from subdirectories is an anti-pattern to be avoided, and is simply not supported by this function.
Parameters¶
Options¶
WITH_TESTS_DIR
Causes the
JCM_PROJECT_TESTS_DIR
directory to be added when the${JCM_PROJECT_PREFIX_NAME}_ENABLE_TESTS
option is set.WITH_DOCS_DIR
Causes the
JCM_PROJECT_DOCS_DIR
directory to be added when the${JCM_PROJECT_PREFIX_NAME}_ENABLE_DOCS
option is set.ADD_SUBDIRS
Causes this function to add each subdirectory to the project using CMake’s
add_subdirectory()
One Value¶
OUT_VAR
The named variable will be set to the list of resultant subdirectories
Multi Value¶
LIB_COMPONENTS
A list of library components for which subdirectories will be computed. Components matching
PROJECT_NAME
will be ignored.EXEC_COMPONENTS
A list of executable components for which subdirectories will be computed. Components matching
PROJECT_NAME
will be ignored.
Examples¶
jcm_source_subdirectories(
WITH_TESTS_DIR
WITH_DOCS_DIR
OUT_VAR mylib_subdirectories)
jcm_source_subdirectories(
WITH_TESTS_DIR
WITH_DOCS_DIR
OUT_VAR mylib_subdirectories
ADD_SUBDIRS
LIB_COMPONENTS core extra more)
jcm_collect_subdirectory_targets¶
- jcm_collect_subdirectory_targets¶
jcm_collect_subdirectory_targets( [EXCLUDE_DIRECTORY_REGEX <regex>] [START_DIR <directory>] <OUT_VAR <out-var> >)
Collects all targets created in and under the current directory, or that named in
START_DIR
, into a unique list.
This function recursively traverses directories, descending into all subdirectories provided by the
directory property SUBDIRECTORIES
to collect the targets created in that
directory, as indicated by the directory property BUILDSYSTEM_TARGETS
. The
directories can be optionally excluded from the search by providing a regular expression via
EXCLUDE_DIRECTORY_REGEX
that will be applied to the directory’s normalized,
absolute path. All targets created directly in the directories matching the regex will be omitted,
while targets from their subdirectories will still be collected should they not match the regex.
The result of this function will always be a unique list, even if the global property
ALLOW_DUPLICATE_CUSTOM_TARGETS
is set.
Parameters¶
One Value¶
OUT_VAR
The named variable will be set to the list of resultant targets
START_DIR
An optional path to an existent directory that will be used as the starting directory in the traversal. A relative path will first be converted to its normalized, absolute form with respect to
CMAKE_CURRENT_SOURCE_DIR
. Should this be omitted, traversal will begin at${CMAKE_CURRENT_SOURCE_DIR}
.EXCLUDE_DIRECTORY_REGEX
An optional regular expression that will be used to filter directories from the search.
Examples¶
jcm_collect_subdirectory_targets(OUT_VAR all_project_targets)
jcm_transform_list(ALIASED_TARGET
INPUT "${all_project_targets}"
OUT_VAR all_project_targets)
jcm_collect_subdirectory_targets(
EXCLUDE_DIRECTORY_REGEX "build.*"
OUT_VAR all_project_targets)
jcm_collect_subdirectory_targets(
START_DIR "../code-gen"
EXCLUDE_REGEX "${PROJECT_SOURCE_DIR}/.*code-gen/.*database"
OUT_VAR code_gen_targets)
JcmTargetSources¶
jcm_add_target_sources¶
- jcm_add_target_sources¶
jcm_add_target_sources( [WITHOUT_FILE_NAMING_CHECK] <TARGET <target>> <[INTERFACE_HEADERS <header>...] [PUBLIC_HEADERS <header>...] [PRIVATE_HEADERS <header>...] [SOURCES <source>...] >)
After validating and cleaning the paths of the provided sources with
jcm_verify_sources()
, adds them to the given target, TARGET
, using
CMake’s built-in target_sources()
command and JCM’s
jcm_header_file_sets()
. Alias targets are supported, unlike
target_sources()
.
This function will:
for the detected target type, given by the target’s
TYPE
property, ensure the appropriate source file types are provided based on theINTERFACE_HEADERS
,PUBLIC_HEADERS
, andPRIVATE_HEADERS
arguments.transform all input file paths into normalized, absolute paths
verify the file names as conforming to JCM’s file naming conventions based on the regular expressions in JcmFileNaming.cmake
verify the locations of the input files as conforming to the Canonical Project Structure for the given target.
create PRIVATE, PUBLIC, and INTERFACE header sets with
jcm_header_file_sets()
using the respective *_HEADERS parameters and any headers found inSOURCES
for executable targets. This is what sets the *INCLUDE_DIRECTORIES properties.Add the files specified by
PRIVATE_HEADERS
andSOURCES
as private target sources viatarget_sources()
This function is designed for use with both executable and library targets. As such, should the
target’s TYPE
property be an executable, headers and source files may be
provided via the SOURCES
argument. For library targets, headers must be provided
in the INTERFACE_HEADERS
, PUBLIC_HEADERS
, and
PRIVATE_HEADERS
arguments, as header files in SOURCES
will be
rejected by naming convention filters.
Parameters¶
Options¶
WITHOUT_FILE_NAMING_CHECK
When provided, will forgo the default check that provided header and source files conform to JCM’s file naming conventions
One Value¶
TARGET
Names an existing target onto which the provided source will be added.
Multi Value¶
INTERFACE_HEADERS
A list of relative or absolute paths to header files required by consumers of the potential target, but not by the target itself. Interface header files, and therefore this parameter, are only meaningful for library targets. Required when
TARGET_TYPE
is INTERFACE_LIBRARY.PUBLIC_HEADERS
A list of relative or absolute paths to header files required by consumers of the potential target, and by the target itself. Prohibited when
TARGET_TYPE
is INTERFACE_LIBRARY.PRIVATE_HEADERS
A list of relative or absolute paths to header files required exclusively by the target itself; not by consumers of the potential target. Prohibited when
TARGET_TYPE
is INTERFACE_LIBRARY.SOURCES
A list of relative or absolute paths to sources files to build the potential target. Prohibited when
TARGET_TYPE
is INTERFACE_LIBRARY. For executable targets, private header files may be included in this list, and will have the same effect as providing them throughPRIVATE_HEADERS
. For other target types, any header files found in this parameter will cause an error.
Examples¶
jcm_add_target_sources(
TARGET libgeometry::2d
PUBLIC_HEADERS "shapes.hpp" "intersections.hpp"
PRIVATE_HEADERS "shape_theory.hpp"
SOURCES "shapes.cpp" "shape_theory.cpp")
jcm_add_target_sources(
TARGET netman::netman
SOURCES
"main.cpp"
"cli.hpp"
"cli.cpp"
"protocols.hpp"
"protocols.cpp"
"buffers.hpp"
"buffers.cpp"
"tracing.hpp")
jcm_verify_sources¶
- jcm_verify_sources¶
jcm_verify_sources( [WITHOUT_FILE_NAMING_CHECK] [TARGET_TYPE <STATIC_LIBRARY | MODULE_LIBRARY | SHARED_LIBRARY | OBJECT_LIBRARY | INTERFACE_LIBRARY | EXECUTABLE> ] [TARGET_SOURCE_DIR <dir> ] [TARGET_BINARY_DIR <dir> ] [TARGET_COMPONENT <component>] <[INTERFACE_HEADERS <header>...] [PUBLIC_HEADERS <header>...] [PRIVATE_HEADERS <header>...] [SOURCES <source>...] > <[OUT_INTERFACE_HEADERS <out-var>] [OUT_PUBLIC_HEADERS <out-var>] [OUT_PRIVATE_HEADERS <out-var>] [OUT_SOURCES <out-var] >)
Primarily an internal function to verify the provided source files for a potential target.
Created to factor this repeated verification logic out from jcm_add_library()
,
jcm_add_executable()
, jcm_add_test_executable()
, and
jcm_add_target_sources()
. As such, its operation is important for these “public”
functions.
For a potential target of type TARGET_TYPE
, source directory
TARGET_SOURCE_DIR
, and binary directory TARGET_BINARY_DIR
, this
function will:
for the specified target type, ensure the appropriate source file types are provided based on the
INTERFACE_HEADERS
,PUBLIC_HEADERS
, andPRIVATE_HEADERS
arguments.transform all input file paths into normalized, absolute paths. The results of which will be available through the output variables specified by
OUT_INTERFACE_HEADERS
,OUT_PUBLIC_HEADERS
,OUT_PRIVATE_HEADERS
, andOUT_SOURCES
.verify the file names as conforming to JCM’s file naming conventions based on the regular expressions in JcmFileNaming.cmake
verify the locations of the input files as within
TARGET_SOURCE_DIR
orTARGET_BINARY_DIR
.remove any headers in
SOURCES
, appending them toPRIVATE_HEADERS
, thereby keeping the OUT_* variable categories pure.
This function is designed for use with both executable and library targets. As such, should the
target’s TYPE
property be an executable, header files may be
provided via the SOURCES
argument. For library targets, headers must be provided
in the INTERFACE_HEADERS
, PUBLIC_HEADERS
, and
PRIVATE_HEADERS
arguments, as header files in SOURCES
will be
rejected by naming convention filters.
Trusted values for the target’s source and binary directories are taken as opposed to resolving canonical values from a target name to support usage for targets outside of these directories.
Parameters¶
Options¶
WITHOUT_FILE_NAMING_CHECK
When provided, will forgo the default check that provided header and source files conform to JCM’s file naming conventions
One Value¶
TARGET_TYPE
Specifies the type of the potential target - that is, the target’s TYPE property. When omitted, an undefined library will be assumed. This is undefined to allow the various
BUILD_SHARED_*
options to work as expected. Additionally, this function realistically only changes its behaviour when one of EXECUTABLE or INTERFACE_LIBRARY is specified.TARGET_SOURCE_DIR
Specifies a relative or absolute path to the the source directory in which the potential target would be created. This surrogates the target’s SOURCE_DIR property. Relative paths are considered with respect to
CMAKE_CURRENT_SOURCE_DIR
, which is the argument’s default value.TARGET_BINARY_DIR
Specifies a relative or absolute path to the binary directory for the potential target. This surrogates the target’s BINARY_DIR property. Relative paths are considered
CMAKE_CURRENT_BINARY_DIR
, which is the argument’s default value.TARGET_COMPONENT
Specifies the component of the potential target - whether that’s a library component or an executable component, but is only used in this function for executable components. Within JCM, a target’s component is stored in the custom target property,
COMPONENT
.OUT_INTERFACE_HEADERS
The variable named will be set to a list of cleaned paths to interface headers for the potential target. This will contain the same number of entries as provided in
INTERFACE_HEADERS
.OUT_PUBLIC_HEADERS
The variable named will be set to a list of cleaned paths to public headers for the potential target. This will contain the same number of entries as provided in
PUBLIC_HEADERS
.OUT_PRIVATE_HEADERS
The variable named will be set to a list of cleaned paths to private headers for the potential target. For library targets (
TARGET_TYPE
!= EXECUTABLE), this will contain the same number of entries as provided inPRIVATE_HEADERS
. For executable targets, this will contain a cleaned path for the entries inSOURCES
, and a cleaned path for every header file found inSOURCES
.SOURCES
The variable named will be set to a list of cleaned paths to sources for the potential target. For library targets (
TARGET_TYPE
!= EXECUTABLE), this will contain the same number of entries as provided inSOURCES
. For executable targets, this will contain a cleaned path for the entries inSOURCES
, excluding the cleaned paths for header files found inSOURCES
, which are moved toOUT_PRIVATE_HEADERS
.
Multi Value¶
INTERFACE_HEADERS
A list of relative or absolute paths to header files required by consumers of the potential target, but not by the target itself. Interface header files, and therefore this parameter, are only meaningful for library targets. Required when the target property
TYPE
of the targetTARGET
is INTERFACE_LIBRARY.PUBLIC_HEADERS
A list of relative or absolute paths to header files required by consumers of the potential target, and by the target itself. Prohibited when the target property
TYPE
of the targetTARGET
is INTERFACE_LIBRARY.PRIVATE_HEADERS
A list of relative or absolute paths to header files required exclusively by the target itself; not by consumers of the potential target. Prohibited when the target property
TYPE
of the targetTARGET
is INTERFACE_LIBRARY.SOURCES
A list of relative or absolute paths to sources files to build the potential target. Prohibited when the target property
TYPE
of the targetTARGET
is INTERFACE_LIBRARY. For executable targets, private header files may be included in this list, and will have the same effect as providing them throughPRIVATE_HEADERS
. For other target types, any header files found in this parameter will cause an error.
Examples¶
# for some library target
jcm_verify_sources(
INTERFACE_HEADERS "wrappers_windows.hpp" "wrappers.hpp"
PUBLIC_HEADERS "async_io.hpp" "ply_parser.hpp"
PRIVATE_HEADERS "os_abstractions.hpp"
SOURCES "ply_parser.cpp" "os_abstractions.cpp"
OUT_INTERFACE_HEADERS interface_headers
OUT_PUBLIC_HEADERS public_headers
OUT_PRIVATE_HEADERS private_headers
OUT_SOURCES sources)
# for some executable target
jcm_verify_sources(
TARGET_TYPE "EXECUTABLE"
TARGET_SOURCE_DIR "../"
TARGET_BINARY_DIR "../"
PRIVATE_HEADERS "game_logic.hpp" "static_assets.hpp"
SOURCES "main.cpp" "game_logic.cpp" "static_assets.cpp"
OUT_PRIVATE_HEADERS private_headers
OUT_SOURCES sources)
# for some executable component target
jcm_verify_sources(
TARGET_TYPE "EXECUTABLE"
TARGET_COMPONENT "gui"
TARGET_SOURCE_DIR "${PROJECT_SOURCE_DIR}/netcat/gui"
TARGET_BINARY_DIR "${PROJECT_BINARY_DIR}/netcat/gui"
SOURCES
"main.cpp"
"widgets.hpp"
"widgets.cpp"
"pages.hpp"
"pages.cpp"
OUT_PRIVATE_HEADERS private_headers
OUT_SOURCES sources)
JcmCreateAccessoryTargets¶
Offers functions to create custom, “accessory” targets in a project. Here, “accessory” refers to targets that run development operations, which could be formatting, static analysis, document generation, etc. These targets are not targets offered by a projects, like a library or executable target.
jcm_create_message_target¶
- jcm_create_message_target¶
jcm_create_message_target( NAME <name> LEVEL <TRACE|DEBUG|VERBOSE|STATUS|NOTICE|AUTHOR_WARNING|WARNING|SEND_ERROR|FATAL_ERROR> MESSAGES <message>...)
Creates a custom target with the name specified by NAME
that will emit all of the
messages provided to MESSAGES
at the given log level, LEVEL
.
This function and the generated target are used to easily report messages to users from a target at
a specific log level. This differs from a target running the echo cmake command (cmake -E
echo
) because echo only emits messages to stdout, and without log levels. Alternative solutions
are to use JcmArbitraryScript directly, or generate a script file in project configuration and
create a target that parses it as the command.
Parameters¶
Options¶
ALL
Indicate that the created target should be added to the default build target.
One Value¶
NAME
The name of the custom command to create by invoking this function.
LEVEL
The log level of the messages emitted by the created command.
Multi Value¶
MESSAGES
The string messages that will be emitted by the created command at the given log level.
Examples¶
# messages will only be emitted when target is built, not when project is configured
if(MYLIB_SCHEMA_FILES_FOUND)
add_custom_target(mylib_generate_sources
COMMAND "command to actually generate sources")
else()
jcm_create_message_target(
NAME mylib_generate_sources
LEVEL FATAL_ERROR
MESSAGES "Failed to generate sources with the given schema. Schema error ${err_message}")
endif()
jcm_create_clang_format_targets¶
- jcm_create_clang_format_targets¶
jcm_create_clang_format_targets( [QUIET] [WITHOUT_TOP_LEVEL_CHECK] [SKIP_NONEXISTENT_TARGETS] [STYLE_FILE <path>] [EXCLUDE_REGEX <regex>] [COMMAND <command|target>] [ADDITIONAL_PATHS <path>...] SOURCE_TARGETS <target>...)
Creates custom targets “clang-format” and “clang-format-check” that invoke the clang::format
target, or the provided COMMAND
, on all the sources for the provided
SOURCE_TARGETS
and any additional files within ADDITIONAL_PATHS
.
All styling is provided by the file STYLE_FILE
, which must exist, whether the
default value or an explicit value is used.
The created “clang-format” target will format the files in-place, while
“clang-format-check” will report any formatting errors to the console and exit with an error.
EXCLUDE_REGEX
can filter out unwanted source files of targets
SOURCE_TARGETS
, and will be applied to the files’ absolute paths.
Call find_package(ClangFormat)
in order to introduce the clang::format target before
using this function. However, clang::format need not be available to use this function. In this
situation, the generated “clang-format” and “clang-format-check” targets will emit errors when
built, but CMake configuration will not be hindered.
This function has no effect when it is not called in the top-level project, unless
WITHOUT_TOP_LEVEL_CHECK
is provided.
Parameters¶
Options¶
QUIET
Omits the –verbose option to the underlying clang-format executable.
WITHOUT_TOP_LEVEL_CHECK
Causes this function not check if it’s being called in the top-level project.
SKIP_NONEXISTENT_TARGETS
Causes the function to skip over any non-existent targets named in
SOURCE_TARGETS
. Otherwise, all source targets must exist.
One Value¶
STYLE_FILE
An optional path to clang-format style file containing the rules used to format the files in the created targets. By default,
${PROJECT_SOURCE_DIR}/.clang-format
will be used. The named path will be converted to an absolute, normalized path, and any symlinks will be resolved before providing it to the underlying clang-format command.EXCLUDE_REGEX
A regular expression used to filter out the sources extracted from the targets named in
SOURCE_TARGETS
. Paths matching this regex are not provided to clang-format. The regular expression is applied to the absolute, normalized version of the source file paths.COMMAND
An alternative target or command for clang-format that will be used to format the files. By default, the target clang::format will be used.
Multi Value¶
ADDITIONAL_PATHS
Additional relative or absolute paths to files or directories which will be provided as input to clang-format. All paths will be converted to absolute paths with respect to
CMAKE_CURRENT_SOURCE_DIR
. Directories will be expanded into a list of the enclosed files.SOURCE_TARGETS
Targets whose sources, both header and source files, will be formatted by clang-format.
Examples¶
jcm_create_clang_format_targets(SOURCE_TARGETS libbbq::libbbq)
jcm_create_clang_format_targets(
QUIET
STYLE_FILE .clang-format-14
COMMAND libbbq::customClangFormat
SOURCE_TARGETS libbbq:libbbq
EXCLUDE_REGEX "libbbq_config.hpp$"
ADDITIONAL_PATHS
completely/separate/file.hpp
completely/separate/file.cpp)
jcm_create_doxygen_target¶
- jcm_create_doxygen_target¶
jcm_create_doxygen_target( [README_MAIN_PAGE] [SKIP_NONEXISTENT_TARGETS] [EXCLUDE_REGEX <regex>] [OUTPUT_DIRECTORY <dir>] <[SOURCE_TARGETS <target>...] [ADDITIONAL_PATHS <path>...] >)
Creates a target, “doxygen-docs”, that generates documentation of the provided
SOURCE_TARGETS
’s header files and any ADDITIONAL_PATHS
using
Doxygen. All of the header files in all of the interface header sets of the targets are gathered for
Doxygen, with the exception of those that match EXCLUDE_REGEX
, if provided.
Doxygen will strip include directories from these paths such that the displayed include commands have the proper include paths and not absolute paths. This function will provide all of the include targets’ INTERFACE_INCLUDE_DIRECTORIES, with any generator expressions removed, as include directories for Doxygen to strip.
The following Doxygen related variables are set by this function:
DOXYGEN_STRIP_FROM_INC_PATH
DOXYGEN_OUTPUT_DIRECTORY
DOXYGEN_USE_MDFILE_AS_MAINPAGE
This function has no effect when <JCM_PROJECT_PREFIX>_ENABLE_DOCS
is not set.
Ensure to call find_package(Doxygen)
before using this function.
Parameters¶
Options¶
README_MAIN_PAGE
Sets DOXYGEN_USE_MDFILE_AS_MAINPAGE to the project’s root README.md file, such that Doxygen will use the project’s readme as the main page.
SKIP_NONEXISTENT_TARGETS
Causes the function to skip over any non-existent targets named in
SOURCE_TARGETS
. Otherwise, all source targets must exist.
One Value¶
EXCLUDE_REGEX
A regular expression used to filter out the headers extracted from the targets named in
SOURCE_TARGETS
. The header file absolute paths matching this regex are not provided to Doxygen.OUTPUT_DIRECTORY
Directory where the documentation will be placed. By default, this is is
${CMAKE_CURRENT_BINARY_DIR}/doxygen
.
Multi Value¶
SOURCE_TARGETS
Targets whose interface header files will be documented by Doxygen
ADDITIONAL_PATHS
Additional relative or absolute paths to files or directories which will be provided as input to Doxygen. All paths will be converted to absolute paths with respect to
CMAKE_CURRENT_SOURCE_DIRECTORY
. Directories will be passed directly to Doxygen.
Examples¶
jcm_create_doxygen_target(
README_MAIN_PAGE
SOURCE_TARGETS libbbq::libbbq)
jcm_create_doxygen_target(
README_MAIN_PAGE
SOURCE_TARGETS libbbq::libbbq libbbq::vegetarian
EXCLUDE_REGEX "export_macros.hpp$"
ADDITIONAL_PATHS ../completely/separate/file.hpp)
jcm_create_sphinx_target¶
- jcm_create_sphinx_target¶
jcm_create_sphinx_target( [CONFIGURE_CONF_PY] [BUILDER <builder>] [COMMAND <command|target>] [SOURCE_DIRECTORY <dir>] [BUILD_DIRECTORY <dir>])
Creates custom target “sphinx-docs” which invokes the Sphinx::build target, or the provided
COMMAND
, to generate Sphinx documentation from the default source directory, or
SOURCE_DIRECTORY
if provided. When CONFIGURE_CONF_PY
is set,
Sphinx’s configuration file, conf.py, will be generated by configuring an input template,
conf.py.in, from the source directory to CMAKE_CURRENT_BINARY_DIR
. This will
then be provided as configuration directory path to the sphinx command with its -c option.
Call find_package(Sphinx)
in order to introduce the Sphinx::build target before using
this function. However, Sphinx::build need not be available to use this function. In this
situation, the generated “sphinx-docs” target will emit errors when built, but CMake configuration
will not be hindered.
This function has no effect when <JCM_PROJECT_PREFIX>_ENABLE_DOCS
is not set.
Parameters¶
Options¶
CONFIGURE_CONF_PY
When provided, this function will configure Sphinx’s configuration file, conf.py, as described above.
One Value¶
BUILDER
Sphinx builders specify which type of documentation should be generated. Options include ‘html’, ‘text’, ‘latex’, and more. The default is html.
COMMAND
An alternative target or command that will be used to format the files. By default, the target Sphinx::build will be used.
SOURCE_DIRECTORY
The source directory, where the documentation files live, provided to the sphinx command/target. A relative path will be treated as relative with respect to
CMAKE_CURRENT_SOURCE_DIR
. Default value isCMAKE_CURRENT_SOURCE_DIR
.BUILD_DIRECTORY
The build directory, where the documentation will be generated, provided to the sphinx command/target. A relative path will be treated as relative with respect to
CMAKE_CURRENT_BINARY_DIR
. Default value is${CMAKE_CURRENT_BINARY_DIR}/sphinx
Examples¶
jcm_create_sphinx_targets(CONFIGURE_CONF_PY)
jcm_create_sphinx_targets(
CONFIGURE_CONF_PY
BUILDER "latex"
BUILD_DIRECTORY "sphinx/latex")
JcmAddOption¶
jcm_add_option¶
- jcm_add_option¶
jcm_add_option( [WITHOUT_NAME_PREFIX_CHECK] NAME <option-name> DESCRIPTION <description> TYPE <BOOL|FILEPATH|PATH|STRING|INTERNAL> DEFAULT <default-value> [CONDITION <condition> CONDITION_MET_DEFAULT <default-value-when-met>] [ACCEPT_VALUES <value>...])
Adds a project build-option using either set()
or
cmake_dependent_option()
, while providing better type support and validation. Like
the CMake built-ins to add options, option()
and
cmake_dependent_option()
, the options introduced by this function are just CACHE
variables that can be used to control the project’s configuration. As opposed to using either of
those CMake built-ins, this function provides:
Named arguments
Access to both independent and dependent build-options from a single function
Option types including those for dependent options, which
cmake_dependent_option()
does not support, and types beyondBOOL
, which is all thatoption()
supports.Validation of the option name being both prefixed by
${JCM_PROJECT_PREFIX_NAME}_
, and being in SCREAMING_SNAKE_CASE. These provide consistency, clarity, and exclusivity of build options between projects. However, this prefix check can be avoided withWITHOUT_NAME_PREFIX_CHECK
, for cases described in the below Parameters.Restrict the option’s value to one of
ACCEPT_VALUES
.
Parameters¶
Options¶
WITHOUT_NAME_PREFIX_CHECK
Skips the internal assertion that the provided option name,
NAME
, is prefixed with${JCM_PROJECT_PREFIX_NAME}_
. This would be used to create project agnostic options, like the commonBUILD_TESTING
.BUILD_TESTING
is merely an example, as JCM will handle this specific option internally.
One Value¶
NAME
The name of the option to create.
DESCRIPTION
A description of the option for builders of the project.
TYPE
The type of the option to create. Must be one of the types available for cache entries:
BOOL
,FILEPATH
,PATH
,STRING
, orINTERNAL
.DEFAULT
The default value of the option should it not already be set in the CMake cache. This value is also used if
CONDITION
is provided to this function but is not met.CONDITION
An optional condition that will make the option a dependent option; dependent upon the provided condition. When provided, CMake’s
cmake_dependent_option
will be used in place ofset()
to create the option.CONDITION_MET_DEFAULT
The default value of the option when
CONDITION
is provided to this function and the condition is met. LikeDEFAULT
, when a value for the option already exists in the cache, it will be used in place of this default.
Multi Value¶
ACCEPT_VALUES
Acceptable values of the created option. When provided, the
STRINGS
property on the created cache entry will be set, and a fatal error will be emitted if the value of this option is not one of these declared values.
Examples¶
jcm_add_option(
NAME ${PROJECT_NAME}_ENABLE_INTEGRATION_TESTS
DESCRIPTION "Enables the automated integration tests"
TYPE BOOL
DEFAULT ${PROJECT_NAME})
jcm_add_option(
NAME ${PROJECT_NAME}_COMPRESSION_BACKEND
DESCRIPTION "Selects the compression backend to use for transport compression"
TYPE STRING
DEFAULT "NONE"
CONDITION "${PROJECT_NAME}_ENABLE_TRANSPORT_LAYER"
ACCEPT_VALUES "NONE;ZIP;BROTLI;LZ")
jcm_add_option(
NAME BUILD_SHARED_LIBS
DESCRIPTION "Build libraries with unspecified types shared."
WITHOUT_NAME_PREFIX_CHECK
TYPE BOOL
DEFAULT OFF)
jcm_add_option(
NAME ${JCM_PROJECT_PREFIX_NAME}_BUILD_SHARED_LIBS
DESCRIPTION "Build libraries of project ${PROJECT_NAME} with unspecified types shared."
TYPE BOOL
DEFAULT ${BUILD_SHARED_LIBS})
jcm_add_component_options¶
- jcm_add_component_options¶
jcm_add_component_options( [REQUIRED_COMPONENTS <component>...] [DEFAULT_OFF_COMPONENTS <component>...] <OPTIONAL_COMPONENTS <component>...> <[OUT_COMPONENTS <out-var>] > [OUT_TARGETS <out-targets>] > [<COMPONENT_DEPENDENCIES_JSON <json> <MISSING_DEPENDENCY_ACTION <ENABLE|ERROR> > ])
Creates build options with jcm_add_option()
named
${JCM_PROJECT_PREFIX_NAME}_ENABLE_<component>, where component is the name of a standard project
component, i.e a library or executable component. An option will be for every component in the list
OPTIONAL_COMPONENTS
. The result variables will contain all optional components
that have been enabled by their respective build option, and all required components; those named
in REQUIRED_COMPONENTS
.
Every project component produces a single installed target. Targets can be selectively built by CMake with the command-line option –target, such as cmake –build build –target libcomponents_libcomponents-core, which will exclusively build the core component of project libcomponents. However, the configuration of undesired components may also be worth avoiding if their configuration is very long or introduces additional dependencies. For example, if the extra component of libcomponents requires eight dependencies that aren’t required by core, users of core may not want to acquire dependencies they don’t use. For this purpose, project options can be introduced to selectively configure project components.
This function is merely a wrapper around :cmake:command`jcm_add_option` adding simplicity and consistency for the use-case. Using this function does not preclude creating any project options through other means, nor do all project components need to be provided to this function.
Component names cannot have any regex characters in them
Parameters¶
Option¶
OUT_COMPONENTS
The variable named will be set to the list of enabled components.
One Value¶
OUT_COMPONENTS
The variable named will be set to the list of enabled components.
OUT_TARGETS
The variable named will be set to the list of enabled targets derived from the enabled components by prefixing each with ${PROJECT_NAME}::.
COMPONENT_DEPENDENCIES_JSON
Optional string containing a JSON document detailing the components dependencies on one another. The document structure is an object where keys are names of optional components, and values are arrays of component names. When the component named by one of the object entries is enabled by its respective build option, all the build options for the components named in the value array will also be enabled. Although unnecessary, required component can be named in the value array.
This argument must be accompanied by
MISSING_DEPENDENCY_ACTION
.MISSING_DEPENDENCY_ACTION
Optional literal of either ERROR or ENABLE indicating what action will be taken when a component named in
COMPONENT_DEPENDENCIES_JSON
is enabled but a dependency in its dependency array is not. A value of ENABLE will set the project option of the disabled dependency component to enable it. A value of ERROR will emit a fatal error.This argument must be accompanied by
COMPONENT_DEPENDENCIES_JSON
.
Multi Value¶
OPTIONAL_COMPONENTS
Required list of optional project components that will have build options created for them.
REQUIRED_COMPONENTS
Optional list of project components that are always configured and do not have respective options to disable them. The components named are always considered “enabled” and will appear unaltered in the variable named by
OUT_COMPONENTS
. This option is included to declaratively indicate which components are required by a project, and make downstream handling of enabled components simpler.DEFAULT_OFF_COMPONENTS
Optional list of optional project components who’s associated project option will be created with a default value of OFF instead of ON. As such, configuring a project using its default options will not enable the components named in this list. Builders will have to explicitly enable them through their respective project option.
Examples¶
jcm_add_component_options(
REQUIRED_COMPONENTS "core"
OPTIONAL_COMPONENTS "io" "extra"
DEFAULT_OFF_COMPONENTS "extra"
OUT_COMPONENTS enabled_components)
jcm_add_component_options(
REQUIRED_COMPONENTS "core"
OPTIONAL_COMPONENTS "io" "extra"
DEFAULT_OFF_COMPONENTS "extra"
OUT_COMPONENTS enabled_components
MISSING_DEPENDENCY_ACTION "ENABLE"
COMPONENT_DEPENDENCIES_JSON [=[
{
"extra": [ "io", "core" ],
"io": [ "core" ]
}
]=])
JcmBasicPackageConfig¶
Provides macros to create Config-file Packages. Offers
the jcm_basic_package_config()
macro for top-level config-files, and the
jcm_basic_component_config()
macro for config-files of individual components.
The utilities here follow a pattern of each target providing its on config-file and targets-file. This makes managing inter-project dependencies very easy and simplifies overall logic.
jcm_basic_package_config¶
- jcm_basic_package_config¶
jcm_basic_package_config( <project> [NO_TARGETS])
Provides all CMake commands that are required in a package config-files to create relocatable,
config-file packages. Call this macro at the end of your package config-file template
(<project>-config.cmake.in), after @PACKAGE_INIT@
.
This macro will:
include the associated targets file from the current list directory, if
NO_TARGETS
is omittedinclude the config files for the components requested by the consumer’s
find_package()
call, or all of those installed, if no components are explicitly requested. Requested components of ${project} are ignored.if any CMake modules not corresponding to config-file packages (not config files, targets files, or version files…) exist in
CMAKE_CURRENT_LIST_DIR
, the directory will be appended toCMAKE_MODULE_PATH
so consumers have access to these additional modules.call
check_required_components()
, as KitWare recommends at the end of every package config-file. To get this macro inPACKAGE_INIT
, ensure your config-file template is configured throughconfigure_package_config_file()
, or preferrably enable configuring injcm_install_config_file_package()
.
Parameters¶
Positional¶
project
The name of the project being packaged. Don’t use
${PROJECT_NAME}
, as this will resolve to the consuming project’s name.
One Value¶
NO_TARGETS
Indicates that this package does not provide any CMake targets at the top-level, causing this macro to skip inclusion of a targets file (<project>-targets.cmake). Consider a CMake library, for instance, or a library with components providing their own targets files.
Examples¶
Most package config files will take this form.
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(jgd-cmake-modules CONFIG REQUIRED)
include(JcmBasicPackageConfig)
jcm_basic_package_config(@PROJECT_NAME@)
jcm_basic_component_config¶
- jcm_basic_component_config¶
jcm_basic_component_config( <project> <component> [REQUIRED_COMPONENTS <component>...] [NO_TARGETS])
Provides all CMake commands that are required in a package config-file of an individual project component (<project>-<component>-config.cmake).
This macro will:
include the config-files of any dependent components
include the current component’s associated targets file from the current list directory
set the component’s associated
<project>_<component>_FOUND
variables thatcheck_required_components()
uses.
Parameters¶
Positional¶
project
The name of the project being packaged. Don’t use
${PROJECT_NAME}
, as this will resolve to the consuming project name.component
The name of the component provided by this config-file.
One Value¶
NO_TARGETS
Indicates that this package does not provide any CMake targets, causing this macro to skip inclusion of a targets file (<project>-<component>-targets.cmake). The requirement for the presence of the expected target will also be skipped before setting
<project>_<component>_FOUND
toTRUE
.
Multi Value¶
REQUIRED_COMPONENTS
Other components of the same project that this component depends upon.
Examples¶
Most package config files will take this form. Examples represent the components’ config-files for a fantasy project, libvideo, offering components core, compression, stream, and freemium.
jcm_basic_component_config(@PROJECT_NAME@ core)
jcm_basic_component_config(@PROJECT_NAME@ compression REQUIRED_COMPONENTS core)
jcm_basic_component_config(@PROJECT_NAME@ stream REQUIRED_COMPONENTS core compression)
jcm_basic_component_config(@PROJECT_NAME@ freemium REQUIRED_COMPONENTS core)
JcmInstallConfigFilePackage¶
jcm_install_config_file_package¶
- jcm_install_config_file_package¶
jcm_install_config_file_package( [CONFIGURE_PACKAGE_CONFIG_FILES] <[TARGETS <target>...] [CMAKE_MODULES <path>...] [INSTALL_LICENSES] >)
Provides ability to consistently and reliably create a project’s config-file package install rules
in one command. All of the named TARGETS
, CMAKE_MODULES
, and
licenses will be installed to paths provided by GNUInstallDirs with appropriate package
config-files, version file, and targets files. Package config-files will be installed from
JCM_PROJECT_CMAKE_DIR
or JCM_INSTALL_CMAKE_DESTINATION
if they
were configured with some derivative of configure_file()
.
Each target will be installed with an associated targets file. The target will be exported within
the namespace ${PROJECT_NAME}::
, which includes the key “::” characters and follows common
conventions. Executables and shared libraries will be installed under the install component
${PROJECT_NAME}_runtime
, while static libraries and headers in the target’s INTERFACE and
PUBLIC header sets will be installed under the ${PROJECT_NAME}_devel
install component.
This supports separate runtime and development packages often distributed by package managers. Alias
targets are supported (libsample::libsample).
CMAKE_MODULES
will be installed under the ${PROJECT_NAME}_devel
install
component. If any of the paths in this list name a directory, the directory will be expanded to a
list of all enclosed files ending in .cmake. Relative paths are converted to absolute paths with
respect to CMAKE_CURRENT_SOURCE_DIR
.
Licenses are installed under JCM_INSTALL_DOC_DIR
. Both a root LICENSE.* file and
licenses within JCM_PROJECT_LICENSES_DIR
will be installed. Symlinks are followed
until a file is reached, ensuring to install the license file with the original name of the symlink.
Intermediate symlinks are not installed.
The following project options are created:
- <JCM_PROJECT_PREFIX_NAME>_ENABLE_INSTALL
Boolean controlling whether the install rules produced by this function are generated or not. The default value is that of
PROJECT_IS_TOP_LEVEL
, meaning installation rules are generated when the project is top-level. Whether or not the project is top-level, use this option to override this behaviour, such as generating install rules when the project is not top-level.
- <JCM_PROJECT_PREFIX_NAME>_INSTALL_VERSIONED_PATHS
Boolean controlling whether the install rules produced by this function will install to versioned paths or not. This does not affect the config-file package’s version-file which is always installed. The default value is
ON
, meaning installation paths will include the project’s version (supported by CMake’sfind_package
). This allows installing multiple versions of the same project in the same installation root, and prevents overwriting existing installations of the same project. When turnedOFF
, theUNVERSIONED
variants of the variables dictating install destinations from JcmStandardDirs will be used in place of those mentioned above. For example: JCM_INSTALL_DOC_DIR -> JCM_UNVERSIONED_INSTALL_DOC_DIR.
Parameters¶
Options¶
CONFIGURE_PACKAGE_CONFIG_FILES
When provided, the config-files will be configured using
jcm_configure_package_config_file()
INSTALL_LICENSES
Causes this function to install licenses from the paths described above. Should there be no licenses in these paths, an author warning will be emitted and installation of other files will continue without hindrance.
Multi Value¶
TARGETS
A list of targets to install.
CMAKE_MODULES
Relative or absolute paths to additional CMake modules, or directories containing CMake modules, to install.
Examples¶
jcm_install_config_file_package(TARGETS libbbq::libbbq)
jcm_install_config_file_package(
CONFIGURE_PACKAGE_CONFIG_FILES
INSTALL_LICENSES
TARGETS libbbq::core libbbq::meat libbbq::veg
CMAKE_MODULES "${JCM_PROJECT_CMAKE_DIR}")
JcmDefaultCompileOptions¶
Defines variables with default compile options for common compilers. These are used to initialize the COMPILE_OPTIONS properties when library or executable targets are created with JCM functions. Of course, like any of the defaults introduced by JCM, these can easily be overridden on the target after it’s created.
Note
Only CXX_COMPILER_ID and C_COMPILER_ID are currently considered. This is to be extended to other languages
The following variables are defined:
JCM_DEFAULT_CXX_COMPILE_OPTIONS_GNU
-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Weffc++ -Wno-non-virtual-dtor
JCM_DEFAULT_C_COMPILE_OPTIONS_GNU
-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion
JCM_DEFAULT_CXX_COMPILE_OPTIONS_CLANG
Same as
JCM_DEFAULT_CXX_COMPILE_OPTIONS_GNU
JCM_DEFAULT_C_COMPILE_OPTIONS_CLANG
Same as
JCM_DEFAULT_C_COMPILE_OPTIONS_GNU
JCM_DEFAULT_CXX_COMPILE_OPTIONS_MSVC
/W4 /WX
JCM_DEFAULT_C_COMPILE_OPTIONS_MSVC
Same as
JCM_DEFAULT_CXX_COMPILE_OPTIONS_MSVC
JCM_DEFAULT_COMPILE_OPTIONS
A generator expression that will resolve to the appropriate set of the variables above based on the compiler and language. This is used to initialize targets’ COMPILE_OPTIONS.
JcmTargetNaming¶
jcm_library_naming¶
- jcm_library_naming¶
jcm_library_naming( [PROJECT <project-name>] [COMPONENT <component>] <[OUT_TARGET <target>] [OUT_EXPORT_NAME <out-var>] [OUT_OUTPUT_NAME <out-var>] >)
Sets the output variable specified by the OUT_* arguments to default, consistent, unique library names that libraries can use to initialize their naming properties.
Parameters¶
One Value¶
PROJECT
The project to which the library belongs. The project name is used in the library names to ensure uniqueness in super-builds.
PROJECT_NAME
will be used by default.COMPONENT
The project component that this library represents. The component is used in the library names.
OUT_TARGET
The variable named will be set to the resultant target name for a library of the specified project that provides the specified component.
OUT_EXPORT_NAME
The variable named will be set to the resultant export name for the library, that should be used to initialize the EXPORT_NAME target property.
OUT_OUTPUT_NAME
The variable named will be set to the resultant export name for the library, that should be used to initialize the OUTPUT_NAME target property.
jcm_executable_naming¶
- jcm_executable_naming¶
jcm_executable_naming( [PROJECT <project-name>] [COMPONENT <component>] <OUT_TARGET <target> OUT_EXPORT_NAME <out-var> OUT_OUTPUT_NAME <out-var>>)
Sets the output variable specified by the OUT_* arguments to default, consistent, unique executables names that executables can use to initialize their naming properties.
Parameters¶
One Value¶
PROJECT
The project to which the executable belongs. The project name is used in the executable names to ensure uniqueness in super-builds.
PROJECT_NAME
will be used by default.COMPONENT
The project component that this executable represents. The component is used in the executable names.
OUT_TARGET
The variable named will be set to the resultant target name for an executable of the specified project that provides the specified component.
OUT_EXPORT_NAME
The variable named will be set to the resultant export name for the executable, that should be used to initialize the EXPORT_NAME target property.
OUT_OUTPUT_NAME
The variable named will be set to the resultant export name for the executable, that should be used to initialize the OUTPUT_NAME target property.
jcm_target_type_component_from_name¶
- jcm_target_type_component_from_name¶
jcm_target_type_component_from_name( [PROJECT <project-name>] TARGET_NAME <target> <[OUT_TYPE <target>] [OUT_COMPONENT <out-var>] >)
JCM’s target naming conventions denote both the the target’s type and component within the naming structure. This function will, considering the project name, compute the target type and component from a given target name. The named target doesn’t have to exist.
Parameters¶
One Value¶
PROJECT
The project to which the target belongs. Since project names are embedded within target names, it must be known in deduction.
PROJECT_NAME
will be used by default.TARGET_NAME
A target name following JCM’s target naming conventions that the target type and component will be computed from.
OUT_TYPE
The variable named will store the computed target type
OUT_COMPONENT
The variable named will store the computed component or an empty string if the target is not a project component.
Examples¶
jcm_target_type_component_from_name(
PROJECT libssh
TARGET_NAME libssh::libssh
TARGET_TYPE type
TARGET_COMPONENT component)
jcm_aliased_target¶
- jcm_aliased_target¶
jcm_aliased_target( TARGET <target> OUT_TARGET <out-var>)
Recursively searches the chain of alias targets named by TARGET
until a
non-alias target is found. The name of the first non-alias target encountered in this search will
be placed in the variable specified by OUT_TARGET
. Consequently, the resulting
target name will be that of a non-alias target. Should TARGET
not be an alias
target, it’s name will simply be the result. A fatal error will be emitted if any target name in
this search does not name an actual target.
Parameters¶
One Value¶
TARGET
OUT_TARGET
Examples¶
jcm_aliased_target(
TARGET libformat::io
OUT_TARGET aliased_target)
message(STATUS "libformat_libformat-io == ${aliased_target}")
JcmFileNaming¶
Provides variables and functions to help enforce file naming conventions.
For each of the enabled languages at the point of inclusion, as per the global ENABLED_LANGUAGES property, the following variables are defined. These contain regular expressions for suitable file names for the given language. Supported languages are currently C,CXX,CUDA,OBJC,OBJCXX,HIP
JCM_<LANG>_HEADER_REGEX
JCM_<LANG>_SOURCE_REGEX
JCM_<LANG>_UTEST_SOURCE_REGEX
The following variables provide cumulative regular expressions for all the enabled languages encountered to the point of inclusion. These are built by joining the variables above with the ‘|’ character.
JCM_HEADER_REGEX
JCM_SOURCE_REGEX
JCM_UTEST_SOURCE_REGEX
Additional, non-languages specific variables with regular expressions for file names are introduced:
JCM_CMAKE_MODULE_REGEX
. This is for normal CMake modules, not package-config files.JCM_IN_FILE_REGEX
JCM_CXX_MODULE_REGEX
jcm_package_config_file_name¶
- jcm_package_config_file_name¶
jcm_package_config_file_name( [PROJECT <project>] [COMPONENT <component>] OUT_VAR <out-var> )
Constructs a consistent kebab-case package configuration file name based on the
PROJECT
, which defaults to PROJECT_NAME
, and
COMPONENT
, if provided. The resulting file name will be placed in the variable
specified by OUT_VAR
. Result will be <PROJECT>-[COMPONENT-]config.cmake.
Parameters¶
One Value¶
PROJECT
The project that the config-file packages, if the default value of
PROJECT_NAME
is not correct.COMPONENT
Specifies the component that the file will describe. A
COMPONENT
that matchesPROJECT_NAME
orPROJECT
will be ignored.OUT_VAR
The variable named will be set to the resultant file name
Examples¶
# PROJECT_NAME is libgarden
# file_name will be libgarden-config.cmake
jcm_package_config_file_name(OUT_VAR file_name)
# file_name will be libimage-core-config.cmake
jcm_package_config_file_name(
PROJECT libimage
COMPONENT core
OUT_VAR file_name
)
jcm_package_version_file_name¶
- jcm_package_version_file_name¶
jcm_package_version_file_name( [PROJECT <project>] OUT_VAR <out-var> )
Constructs a consistent kebab-case package version file name based on the PROJECT
,
which defaults to PROJECT_NAME
. The resulting file name will be placed in the
variable specified by OUT_VAR
. Result will be <PROJECT>-version.cmake.
Parameters¶
One Value¶
PROJECT
The project that the version file represents, if the default value of
PROJECT_NAME
is not correct.OUT_VAR
The variable named will be set to the resultant file name
Examples¶
# PROJECT_NAME is libgarden
# file_name will be libgarden-version.cmake
jcm_package_version_file_name(OUT_VAR file_name)
jcm_package_targets_file_name¶
- jcm_package_targets_file_name¶
jcm_package_targets_file_name( [PROJECT <project>] [COMPONENT <component>] OUT_VAR <out-var> )
Constructs a consistent kebab-case package targets file name based on the PROJECT
,
which defaults to PROJECT_NAME
, and COMPONENT
, if provided. The
resulting file name will be placed in the variable specified by OUT_VAR
. Result
will be <PROJECT>-[COMPONENT-]targets.cmake. The target’s file naming scheme includes a component
because JCM installs one targets file per target for simpler management.
Parameters¶
One Value¶
PROJECT
The project that the targets file contains targets for, if the default value of
PROJECT_NAME
is not correct.COMPONENT
Specifies the component that the file will describe. A
COMPONENT
that matchesPROJECT_NAME
orPROJECT
will be ignored.OUT_VAR
The variable named will be set to the resultant file name
Examples¶
# PROJECT_NAME is libgarden
# file_name will be libgarden-targets.cmake
jcm_package_targets_file_name(OUT_VAR file_name)
# file_name will be libimage-core-targets.cmake
jcm_package_targets_file_name(
PROJECT libimage
COMPONENT core
OUT_VAR file_name
)
JcmCanonicalStructure¶
Specifications in Canonical Project Structure, implemented in CMake. This modules concerns itself with source subdirectories, include directories, the ‘lib’ prefix, and file extensions. Actual file naming is implemented in JcmFileNaming, which uses the file extensions defined here.
Note
This module is often just an implementation detail of JCM, and doesn’t need to be used directly.
Variables¶
The file extensions specified by the Canonical Project Structure have been extended for the CMake recognized languages of CXX, C, CUDA, OBJC, OBJCXX, and HIP.
JCM_LIB_PREFIX
The prefix used throughout JCM for libraries. Used in project names and when naming targets. Set as ‘lib’ from Canonical Project Structure.
JCM_IN_FILE_EXTENSION
File extension used for input files that will undergo substitution through some version of
configure_file()
. This is a custom file extension for JCM, placed here for unity.JCM_<LANG>_HEADER_EXTENSION
File extension for header files. ‘.hpp’ option selected from Canonical Project Structure for C++
JCM_<LANG>_SOURCE_EXTENSION
File extension for source files. ‘.cpp’ option selected from Canonical Project Structure for C++
JCM_<LANG>_UTEST_SOURCE_EXTENSION
File extension for unit testing source files. ‘.test.cpp’ option selected from Canonical Project Structure for C++
JCM_CXX_MODULE_EXTENSION
File extension for module interface files. ‘.mpp’ option selected from Canonical Project Structure
JCM_PROJECT_CANONICAL_SUBDIR_PREFIX_REGEX
A regular expression describing the path prefix for every canonical subdirectory for the current project, given by
PROJECT_NAME
. An absolute, normalized path matching this regular expression is a canonical subdirectory for the current project.
jcm_canonical_subdir¶
- jcm_canonical_subdir¶
jcm_canonical_subdir( OUT_VAR <out-var> TARGET <target>)
Sets the variable specified by OUT_VAR
to the canonical source subdirectory for
either an executable or library of project PROJECT_NAME
. Calls either
jcm_canonical_lib_subdir()
or jcm_canonical_exec_subdir()
based on the
target TYPE property, or the deduced type from the target name, if the target is
not yet created.
Parameters¶
One Value¶
OUT_VAR
The variable named will be set to the computed subdirectory
TARGET
The name of the target for which the path will be computed.
Examples¶
project(ssh VERSION 0.0.0)
...
jcm_canonical_subdir(OUT_VAR ssh_subdir TARGET ssh::ssh)
message(STATUS "${ssh_subdir}") # ssh/ssh
project(ssh VERSION 0.0.0)
...
jcm_canonical_subdir(OUT_VAR cli_subdir TARGET ssh::cli)
message(STATUS "${cli_subdir}") # ssh/ssh/cli
jcm_canonical_lib_subdir¶
- jcm_canonical_lib_subdir¶
jcm_canonical_lib_subdir( OUT_VAR <out-var> [COMPONENT <component>])
Sets the variable specified by OUT_VAR
to the canonical source subdirectory for a
library of project PROJECT_NAME
. In the following descriptions, name is the
PROJECT_NAME
without any lib prefix (libproj -> proj).
When COMPONENT
is omitted, the output will be the canonical project path for a
single library of PROJECT_NAME
, regardless of if PROJECT_NAME
names a library or executable. The resulting path is absolute, and will be
/<JCM_LIB_PREFIX><name>, with respect to PROJECT_SOURCE_DIR
.
When COMPONENT
is provided, the output will name a library component, considering
the PROJECT_NAME
and the COMPONENT
argument. The resulting path
is absolute, and will be /<JCM_LIB_PREFIX><name>-<COMPONENT>/<JCM_LIB_PREFIX><name>/<COMPONENT>,
with respect to the PROJECT_SOURCE_DIR
.
Parameters¶
One Value¶
OUT_VAR
The variable named will be set to the computed subdirectory
COMPONENT
The name of the library component for which the path will be computed.
Examples¶
project(libdecorate VERSION 0.0.0)
...
jcm_canonical_lib_subdir(OUT_VAR main_library_subdir)
message(STATUS "${main_library_subdir}") # libdecorate/libdecorate
project(libdecorate VERSION 0.0.0)
...
jcm_canonical_lib_subdir(OUT_VAR paint_subdir COMPONENT paint)
message(STATUS "${paint_subdir}") # libdecorate/libdecorate-paint/libdecorate/paint
jcm_canonical_lib_subdir(OUT_VAR restore_subdir COMPONENT restore)
message(STATUS "${restore_subdir}") # libdecorate/libdecorate-restore/libdecorate/restore
project(decorate VERSION 0.0.0)
...
jcm_canonical_lib_subdir(OUT_VAR library_subdir)
message(STATUS "${library_subdir}") # libdecorate/libdecorate
project(decorate VERSION 0.0.0)
...
jcm_canonical_lib_subdir(OUT_VAR paint_subdir COMPONENT paint)
message(STATUS "${paint_subdir}") # libdecorate/libdecorate-paint/libdecorate/paint
jcm_canonical_lib_subdir(OUT_VAR restore_subdir COMPONENT restore)
message(STATUS "${restore_subdir}") # libdecorate/libdecorate-restore/libdecorate/restore
jcm_canonical_exec_subdir¶
- jcm_canonical_exec_subdir¶
jcm_canonical_exec_subdir( OUT_VAR <out-var> [COMPONENT <component>])
Sets the variable specified by OUT_VAR
to the canonical source subdirectory for an
executable of project PROJECT_NAME
. In the following descriptions, name is the
PROJECT_NAME
without any lib prefix (libproj -> proj).
When COMPONENT is omitted, the output is the canonical project path for a single executable of
PROJECT_NAME
, regardless of if PROJECT_NAME
names a library or
executable. The resulting path is absolute, and will be /<name>, with respect to
PROJECT_SOURCE_DIR
,
When COMPONENT is provided, the output is the canonical project path for an executable component,
considering the PROJECT_NAME
and the COMPONENT
argument,
regardless of if PROJECT_NAME
names a library or executable. The resulting path is
absolute, and will be /<name>/<COMPONENT>, with respect to PROJECT_SOURCE_DIR
.
Parameters¶
One Value¶
OUT_VAR
The variable named will be set to the computed subdirectory
COMPONENT
The name of the executable component for which the path will be computed.
Examples¶
project(ssh VERSION 0.0.0)
...
jcm_canonical_exec_subdir(OUT_VAR ssh_subdir)
message(STATUS "${ssh_subdir}") # ssh/ssh
project(libdecorate VERSION 0.0.0)
...
jcm_canonical_exec_subdir(OUT_VAR decorate_subdir)
message(STATUS "${decorate_subdir}") # libdecorate/decorate
jcm_canonical_include_dirs¶
- jcm_canonical_include_dirs¶
jcm_canonical_include_dirs( [WITH_BINARY_INCLUDE_DIRS] OUT_VAR <out-var> TARGET <target>)
Sets the variable specified by OUT_VAR
to a list containing the canonical include
directories for the target named by TARGET
.
The provided target’s SOURCE_DIR
, TYPE
, and
COMPONENT
properties will be queried to resolve the target’s include directory in
the source tree. This will be one or two parent directories above the target’s canonical source
directory to establish the include prefix of <PROJECT_NAME>, or <PROJECT_NAME>/<COMPONENT>
when the target is a component. Binary directories PROJECT_BINARY_DIR
and, when
the target is a component, ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-<COMPONENT> can be appended to
the result for generated headers by providing WITH_BINARY_INCLUDE_DIRS
Parameters¶
Options¶
WITH_BINARY_INCLUDE_DIRS
Append the appropriate binary include directories for the provided
TARGET
, while considering its COMPONENT property, to the result.
One Value¶
OUT_VAR
The variable named will be set to a list of the computed include directories.
TARGET
The name of the target to resolve the canonical include directories for.
Examples¶
jcm_canonical_include_dirs(
TARGET libcup::libcup
OUT_VAR source_include_dirs)
message(STATUS "${source_include_dirs} == ${PROJECT_SOURCE_DIR}")
jcm_canonical_include_dirs(
TARGET libcup::mug
OUT_VAR source_include_dirs)
message(STATUS "${source_include_dirs} == ${PROJECT_SOURCE_DIR}/libcup-mug")
jcm_canonical_include_dirs(
WITH_BINARY_INCLUDE_DIRS
TARGET libcup::mug
OUT_VAR include_dirs)
message(STATUS
"${include_dirs} MATCHES ${PROJECT_SOURCE_DIR}/libcup-mug"
"${include_dirs} MATCHES ${PROJECT_BINARY_DIR}/libcup-mug"
"${include_dirs} MATCHES ${PROJECT_BINARY_DIR}")
JcmConfigureFiles¶
Use-case specific configure functions, like CMake’s configure_file()
(link), but with features for
their respective use-case.
All input file names are simply the output file name with JCM_IN_FILE_EXTENSION
(.in) appended.
jcm_configure_package_config_file¶
- jcm_configure_package_config_file¶
jcm_configure_package_config_file( [TARGET <target> | COMPONENT <component>] [OUT_FILE_VAR <out-var>])
Configures the package config-file for the project or for a project component when either
TARGET
or COMPONENT
is provided. The input and out config file
names and locations are internally determined from jcm_package_config_file_name()
,
JCM_PROJECT_CMAKE_DIR
, and JCM_CMAKE_DESTINATION
.
Configuration occurs via CMake’s configure_package_config_file()
, such that the
configured files have access to the PACKAGE_INIT
variable substitution.
Directly use this function to configure package config-files, or commission it from
jcm_install_config_file_package()
with parameter
CONFIGURE_PACKAGE_CONFIG_FILES
.
Parameters¶
One Value¶
TARGET
Target which the configured config-file represents. This target’s COMPONENT property will be extracted to compute the appropriate config-file name. Prefer this if the target is available.
COMPONENT
Project component which the configured config-file represents, used in conjunction with
PROJECT_NAME
to compute the appropriate config-file name. Use this if the respective target is unavailable.OUT_FILE_VAR
The named variable will be set to the absolute path of the output file.
Examples¶
# configure's project's top-level config-file using PROJECT_NAME
jcm_configure_package_config_file()
# configure's libiceream::toppings's config-file
jcm_configure_package_config_file(TARGET libicecream::toppings)
# same as above - PROJECT_NAME is libicecream
jcm_configure_package_config_file(COMPONENT toppings)
jcm_configure_file¶
- jcm_configure_file¶
jcm_configure_file( IN_FILE <file> [OUT_FILE_VAR <out-var>] [DEST_DIR <dest-dir>])
Configures the file specified by IN_FILE
, just like CMake’s
configure_file()
, but follows JCM’s input-file naming conventions, has richer error
checks and messages, uses @ uses substitution only.
The output file will be computed by removing the file extension
JCM_IN_FILE_EXTENSION
from IN_FILE
and configuring the file to
DEST_DIR
(default CMAKE_CURRENT_BINARY_DIR
), replacing @
variables, only. Like configure_file()
, relative input paths are treated with respect
to CMAKE_CURRENT_SOURCE_DIR
.
Use this function when configuring various files for which there is not a specific configure function for, such as headers and sources.
Parameters¶
One Value¶
IN_FILE
A relative or absolute path to the input config-file template. Relative paths will be computed relative to
CMAKE_CURRENT_SOURCE_DIR
, and all paths will be normalized.OUT_FILE_VAR
The variable named will be set to the absolute, normalized file path of the output file
DEST_DIR
A relative or absolute path to the directory into which the configured file will be placed. Relative paths will be computed relative to
CMAKE_CURRENT_BINARY_DIR
, and all paths will be normalized. When omitted, the default value ofCMAKE_CURRENT_BINARY_DIR
will be used.
Examples¶
jcm_configure_file(IN_FILE my_config.hpp.in)
jcm_configure_file(
IN_FILE my_config.hpp.in # WRT CMAKE_CURRENT_SOURCE_DIR
DEST_DIR "gen" # WRT CMAKE_CURRENT_BINARY_DIR
OUT_FILE_VAR generated_file)
jcm_configure_file(
IN_FILE my_config.hpp.in # WRT CMAKE_CURRENT_SOURCE_DIR
DEST_DIR "gen" # WRT CMAKE_CURRENT_BINARY_DIR
OUT_FILE_VAR generated_file)
jcm_configure_vcpkg_manifest_file¶
- jcm_configure_vcpkg_manifest_file¶
jcm_configure_vcpkg_manifest_file()
Configures a config template of a vcpkg manifest file located in
JCM_PROJECT_CMAKE_DIR
to PROJECT_SOURCE_DIR
, using @
substitution, only. This function provides consistency of configuring vcpkg manifests across
projects, and has no effect if the project is not the top-level project. Furthermore, seeing as this
function merely configures a file, it doesn’t prescribe vcpkg as the dependency manager, or the use
of vcpkg in any capacity.
Using the vcpkg toolchain file to operate in manifest mode will invoke vcpkg with the project’s
manifest file before configuring the project. As such, adding dependencies to the template won’t
be found by find_package()
because vcpkg will have already run by the time this
function configures the manifest file, and will therefore not have installed them. Simply configure
the project again, and the updated manifest file will be available for vcpkg.
Examples¶
jcm_configure_vcpkg_manifest_file()
JcmParseArguments¶
jcm_parse_arguments¶
- jcm_parse_arguments¶
jcm_parse_arguments( [WITHOUT_MISSING_VALUES_CHECK] [WITHOUT_UNPARSED_CHECK] [PREFIX <prefix>] <[OPTIONS <keyword>...] [ONE_VALUE_KEYWORDS <keyword>..] [MULTI_VALUE_KEYWORDS <keyword>...] > [REQUIRES_ALL <keyword>...] [REQUIRES_ANY <keyword>...] [REQUIRES_ANY_<n> <keyword>...] [MUTUALLY_EXCLUSIVE <keyword>..] [MUTUALLY_EXCLUSIVE_<n> <keyword>..] [MUTUALLY_INCLUSIVE <keyword>..] [MUTUALLY_INCLUSIVE_<n> <keyword>..] ARGUMENTS <arg>...)
A wrapper around CMake’s cmake_parse_arguments()
that provides sensible defaults,
named arguments, and handles argument validation. Errors will result in fatal errors being emitted.
Parameters¶
Options¶
WITHOUT_MISSING_VALUES_CHECK
When provided, this macro will not check for keywords with missing values in
ARGUMENTS
WITHOUT_UNPARSED_CHECK
When provided, this macro will not check for unparsed keywords in
ARGUMENTS
. That is keywords that were provided but not included in the following lists of keywords.
One Value¶
PREFIX
The prefix for result variables from
cmake_parse_arguments()
, which includes parsed arguments. Default is “ARGS”, so parsed arguments will begin with “ARGS_”.
Multi Value¶
OPTIONS
A list of keywords for arguments that operate as flags. Either they are provided, or they aren’t, but don’t accept values. These argument variables will be defined as FALSE if they aren’t provided. Keyword list.
ONE_VALUE_KEYWORDS
A list of keywords for arguments that require a single value. These argument variables will not be defined if they aren’t provided. Keywords list.
MULTI_VALUE_KEYWORDS
A list of keywords for arguments that require one or more values. These argument variables will not be defined if they aren’t provided. Keyword list.
REQUIRES_ALL
A list of keywords from any of the above keyword lists that are mandatory. If
ARGUMENTS
does not include the keywords listed here, parsing will emit an error.REQUIRES_ANY
A list of keywords from any of the above keyword lists that must have at least one keyword present. If
ARGUMENTS
does not include at least one of the keywords listed here, parsing will emit an error.REQUIRES_ANY_<n>
Where n is an integer in the range [1,3], these three parameters provide the exact same functionality as
REQUIRES_ANY
, but through separate variables so multiple independent constraints can be enforced simultaneously. Each constraints is independently verified.MUTUALLY_EXCLUSIVE
A list of keywords from any of the above keyword lists that are restricted from being provided simultaneously. If
ARGUMENTS
includes more than one of the keywords listed here, parsing will emit an error.MUTUALLY_EXCLUSIVE_<n>
Where n is an integer in the range [1,3], these three parameters provide the exact same functionality as
MUTUALLY_EXCLUSIVE
, but through separate variables so multiple exclusivity constraints can be enforced simultaneously. Each constraint is independently verified.MUTUALLY_INCLUSIVE
A list of keywords from any of the above keyword lists that must be provided together; the presence of any keyword in this list triggers the requirement of every keyword in this list. Should
ARGUMENTS
include one of the keywords listed here but not all of them, parsing will emit an error.MUTUALLY_INCLUSIVE_<n>
Where n is an integer in the range [1,3], these three parameters provide the exact same functionality as
MUTUALLY_INCLUSIVE
, but through separate variables so multiple inclusivity constraints can be enforced simultaneously. Each constraint is independently verified.
Examples¶
function(separate_list)
jcm_parse_arguments(
OPTIONS "USE_PERL_REGEX" "USE_EXTENDED"
ONE_VALUE_KEYWORDS "REGEX;OUT_MATCHED;OUT_MISMATCHED"
MULTI_VALUE_KEYWORDS "INPUT"
REQUIRES_ALL "REGEX;INPUT"
REQUIRES_ANY "OUT_MATCHED;OUT_MISMATCHED"
MUTUALLY_EXCLUSIVE "USE_PERL_REGEX" "USE_EXTENDED"
ARGUMENTS "${ARGN}")
if(ARGS_USE_PERL_REGEX)
# example usage of option
endif()
if(DEFINED ARGS_OUT_MATCHED)
# example usage of one-value argument
endif()
foreach(input IN LISTS ARGS_INPUT)
# example usage of multi-value argument
endforeach()
# ...
endfunction()
# Ok
separate_list(
INPUT "first" "second" "third"
REGEX ".*$d"
OUT_MATCHED ends_with_d)
# Error, INPUT not provided
separate_list(
REGEX ".*$d"
OUT_MATCHED ends_with_d
OUT_MISMATCHED doesnt_end_with_d)
# Error, OUT_MATCHED nor OUT_MISMATCHED provided
separate_list(
INPUT "first" "second" "third"
REGEX ".*$d")
# Error, USE_PERL_REGEX **and** USE_EXTENDED provided
separate_list(
USE_PERL_REGEX
USE_EXTENDED
INPUT "first" "second" "third"
REGEX ".*$d")
JcmStandardDirs¶
Provides variables defining standard project directories for the source, build, and install trees. All installation paths are versioned such that multiple versions of the same project can be installed in the same location. The following variables are set:
JCM_PROJECT_CMAKE_DIR
Location where CMake code, such as config-files and modules, reside.JCM_PROJECT_DATA_DIR
Location where non-code files that still need to be tracked by revision control resideJCM_PROJECT_TESTS_DIR
Location where tests that are not unit-tests reside. For example, integration, performance, smoke tests, etc.JCM_PROJECT_DOCS_DIR
Location where project documentation residesJCM_PROJECT_LICENSES_DIR
Location where project licenses reside. A single license single file can be placed at the project root, though.JCM_CMAKE_DESTINATION
Destination in the build tree for cmake modules. For example, configured cmake modules are configured to this location.JCM_HEADER_DESTINATION
Destination in the build tree for header files. For example, configured header files are configured to this location. This variable is updated based onCMAKE_CURRENT_BINARY_DIR
, and therefore depends on the location of its inclusion.JCM_INSTALL_CMAKE_DESTINATION
Destination in the install tree for cmake modules.JCM_INSTALL_INCLUDE_DIR
Base directory for installed headers. This path is what should be added to consumer’s include paths to use the installed headers.jcm_install_config_file_package()
automatically does this. Refers to a versioned form ofCMAKE_INSTALL_DOCDIR
from GNUInstallDirs.JCM_INSTALL_DOC_DIR
Root directory for installed docs and related files. Refers to a versioned form ofCMAKE_INSTALL_DOCDIR
from GNUInstallDirs.JCM_UNVERSIONED_INSTALL_CMAKE_DESTINATION
Unversioned variant ofJCM_INSTALL_CMAKE_DESTINATION
.JCM_UNVERSIONED_INSTALL_INCLUDE_DIR
Unversioned variant ofJCM_INSTALL_INCLUDE_DIR
with the same semantics.JCM_UNVERSIONED_INSTALL_DOC_DIR
Unversioned variant ofJCM_UNVERSIONED_INSTALL_DOC_DIR
. Contains same value asCMAKE_INSTALL_DOCDIR
from GNUInstallDirs.
JcmHeaderFileSet¶
jcm_header_file_sets¶
- jcm_header_file_sets¶
jcm_header_file_sets( <INTERFACE | PUBLIC | PRIVATE> [TARGET <target>] [HEADERS <file-path>...])
Creates header file-sets of the provided
scope containing the files in HEADERS
for the possibly alias target,
TARGET
.
For each header file-path, the closest canonical include directory, one of those provided by
jcm_canonical_include_dirs()
, will be found. For each canonical include directory
matched, a new header file-set will be created on the TARGET
using the provided
scope if it doesn’t already exist. The original header file will be added to that file-set.
Header file-sets are
an excellent way to manage header files for libraries because they support installing INTERFACE and
HEADER files when the target is installed and support modifying the target’s respective
*INCLUDE_DIRECTORIES properties, as is done by this function. The subset of canonical include
directories that are matched by the provided HEADERS
are added to the target’s
respective *INCLUDE_DIRECTORIES properties, based on the scope, and are wrapped in the
:cmake:$<BUILD_INTERFACE:…> generator expression.
jcm_add_library()
uses this function, and it is often not necessary to use directly,
unless supplementary headers sets are to be added to a target, like in a nested directory.
TODO: support separately creating header sets for integration tests
Note
Use a target’s HEADER_SETS and INTERFACE_HEADER_SETS properties to query its header sets.
Parameters¶
Positional¶
scope
The desired scope of the created file-set. One of INTERFACE, PUBLIC, or PRIVATE
One Value¶
TARGET
The target on which the created header file-sets will be created and *INCLUDE_DIRECTORIES properties will be manipulated.
Multi Value¶
HEADERS
Header file paths to add to the created header file-sets. Each file path will be converted to a normalized, absolute path, with respect to
CMAKE_CURRENT_SOURCE_DIR
.
Examples¶
jcm_header_file_sets(
PUBLIC
TARGET libimage_libimage
HEADERS image.hpp)
# canonical include directory of image.hpp added PUBLICally to libimage_libimage
# now it's available when linking against libimage_libimage
jcm_add_test_executable(
NAME use_image_hpp
SOURCES use_image_hpp.cpp
LIBS libimage_libimage)
JcmListTransformations¶
jcm_separate_list¶
- jcm_separate_list¶
jcm_separate_list( INPUT <item>... <[OUT_MATCHED <out-var>] [OUT_MISMATCHED <out-var>] > <REGEX <regex> | IS_DIRECTORY | IS_SYMLINK | IS_ABSOLUTE | IS_TARGET | EVAL_TRUE> [TRANSFORM <FILENAME|ALIASED_TARGET>])
Separates the elements of list INPUT
into two groups:
OUT_MATCHED
if the element matches the provided filter, and
OUT_MISMATCHED
otherwise. Before matching, the elements can optionally be
transformed by the selected TRANSFORM
, but the elements in the out-variables are
always identical to those provided via INPUT
.
Parameters¶
One Value¶
OUT_MATCHED
The variable named will be set to a list of elements from
INPUT
that matchedREGEX
.OUT_MISMATCHED
The variable named will be set to a list of elements from
INPUT
that did not matchREGEX
.REGEX
When present, this provided regular expression will be the filter used to separate the input elements.
IS_DIRECTORY
When present, the filter used to separate the input elements will match when an element is a directory.
IS_SYMLINK
When present, the filter used to separate the input elements will match when an element is a symlink.
IS_ABSOLUTE
When present, the filter used to separate the input elements will match when an element is an absolute path
IS_TARGET
When present, the filter used to separate the input elements will match when an element names an existent target
EVAL_TRUE
When present, the filter used to separate the input elements will match when an element interpreted as a condition evaluates to true using CMake’s if clause. This is primarily useful for testing a batch of conditions, such as which elements in a list of options are 1/ON/TRUE/YES… vs. 0/OFF/FALSE/NO/NOTFOUND…
TRANSFORM
A transformation to apply to the input before matching. The outputs will not contain this transformation. Currently, only
FILENAME
orALIASED_TARGET
is supported.
Multi Value¶
INPUT
List of elements to split based on
REGEX
.
Examples¶
jcm_separate_list(
REGEX "${JCM_HEADER_REGEX}"
TRANSFORM "FILENAME"
OUT_MISMATCHED improperly_named
INPUT
"${CMAKE_CURRENT_SOURCE_DIR}/thing.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/thINg.hxx")
jcm_separate_list(
IS_DIRECTORY
OUT_MATCHED directories
OUT_MISMATCHED non_directories
INPUT
"/path/to/my/file.txt"
"/path/to/my")
"/path/to/")
message(STATUS "${directories}" == "/path/to/my;/path/to/")
message(STATUS "${non_directories}" == "/path/to/my/file.txt")
jcm_transform_list¶
- jcm_transform_list¶
jcm_transform_list( <ABSOLUTE_PATH [BASE <path>] | NORMALIZE_PATH | PARENT_PATH | FILENAME | ALIASED_TARGET> INPUT <item>... OUT_VAR <out-var>)
Transforms the items in INPUT
with the given transformation into the list
specified by OUT_VAR
.
Parameters¶
Options¶
ABSOLUTE_PATH
A transformation that treats each input item as a path, and converts it to an absolute path, relative to
CMAKE_CURRENT_SOURCE_DIR
orBASE
, if provided. Excludes other transformation options.NORMALIZE_PATH
A transformation that treats each input item as a path, and converts it to a normalized (canonical) path. Excludes other transformation options.
PARENT_PATH
A transformation that treats each input item as a path, and transforms it to its parent path. Excludes other transformation options.
FILENAME
A transformation that treats each input item as a path, and transform it to its file name; the last component in the path. Excludes other transformation options.
ALIASED_TARGET
A transformation that treats each input item as a target name or target alias, and transform it to the target being aliased with
jcm_aliased_target()
. Excludes other transformation options.
One Value¶
OUT_VAR
The variable named will be set to a list of transformed input elements.
BASE
When the selected transformation is
ABSOLUTE_PATH
, this names the absolute path to the directory upon which relative paths will be made absolute. When omitted, the default isCMAKE_CURRENT_SOURCE_DIR
Multi Value¶
INPUT
List of elements to transform.
Examples¶
jcm_transform_list(
ABSOLUTE_PATH
INPUT image.hpp readers.hpp viewer.hpp
OUT_VAR absolute_headers)
jcm_transform_list(
FILENAME
INPUT libimage/image.hpp libimage/readers.hpp libimage/viewer.hpp
OUT_VAR header_file_names)
message(STATUS "${header_file_names} == image.hpp;readers.hpp;viewer.hpp")
jcm_transform_list(
ALIASED_TARGET
INPUT libimage::core libimage::libimage-viewer libimage_libimage-readers
OUT_VAR aliased_targets)
message(STATUS
"${header_file_names} == libimage_libimage-core;libimage_libimage-viewer;libimage_libimage-readers")
jcm_regex_find_list¶
- jcm_regex_find_list¶
jcm_regex_find_list( [MISMATCH] REGEX <regex> <[OUT_IDX <out-var>] [OUT_ELEMENT <out-var>] > INPUT <item>...)
Searches INPUT
for an item that either matches or mismatches
(when MISMATCH
is provided) the regular expression REGEX
.
Parameters¶
Options¶
MISMATCH
Converts the search to find an element that does not match the provided
REGEX
instead of the default.
One Value¶
REGEX
A regular expression to match against the items in
INPUT
.OUT_IDX
The variable named will be set to the found index or -1 if no element could be found.
OUT_ELEMENT
The variable named will be set to the found element or NOTFOUND if no element could be found.
Multi Value¶
INPUT
List of elements to search for a matching item.
Examples¶
file(
GLOB private_dir_files
LIST_DIRECTORIES false
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/private"
"${CMAKE_CURRENT_SOURCE_DIR}/private/*")
jcm_regex_find_list(
MISMATCH
REGEX ".*(${JCM_CXX_HEADER_EXTENSION}|${JCM_CXX_SOURCE_EXTENSION})$"
OUT_IDX misextensioned_idx
INPUT "${private_dir_files}")
JcmExpandDirectories¶
jcm_expand_directories¶
- jcm_expand_directories¶
jcm_expand_directories( OUT_VAR <out-var> GLOB <glob> PATHS <path>...)
For each path in PATHS
, if the path is a directory, the enclosed files matching
GLOB
will be expanded into the list specified by OUT_VAR
. Paths
in PATHS
that refer directly to files will be directly added to the result.
However, all of the resulting paths will be absolute with respect to
CMAKE_CURRENT_SOURCE_DIR
.
Parameters¶
One Value¶
OUT_VAR
The variable named will be set to the resultant list of file paths
GLOB
The globbing expression for files within directory paths. The directory path currently being expanded will be prepended to this, such that only files within the current path are used.
Multi Value¶
PATHS
List of file and directory paths to expand
Examples¶
jcm_expand_directories(
OUT_VAR cmake_module_paths
GLOB *.cmake
PATHS "${JCM_PROJECT_CMAKE_DIR}" "additional/path/special.cmake")
JcmSymlinks¶
Provides functions for working with symbolic links, including those to inspect their availability and to trace a symbolic link chain.
jcm_check_symlinks_available¶
- jcm_check_symlinks_available¶
jcm_check_symlinks_available( <[OUT_VAR <out-var>] [OUT_ERROR_MESSAGE <out-var>] > [USE_CACHE | SUCCESS_CACHE])
Checks if the current build environment has symbolic links available to it by attempting to create
a temporary symbolic link in CMAKE_CURRENT_BINARY_DIR
. The resultant error message
contains a helpful error message with a suggestion for resolving the issue on Windows OSs.
Additionally, the function can use various levels of caching to avoid trying to build the symbolic link upon each invocation.
Parameters¶
Options¶
USE_CACHE
When provided, will cause the function to store the result of the test in the cache variable
JCM_SYMLINKS_AVAILABLE
. Subsequent invocations of this function will use the cached result.SUCCESS_CACHE
When provided, will cause the function to store the result of the test in the cache variable
JCM_SYMLINKS_AVAILABLE
, once the test succeeds. The test will be performed for each subsequent invocation of this function, until the symbolic link can be created, at which point the cached result will be used for further invocations.
One Value¶
OUT_VAR
The variable named will be set to a boolean value, indicating if the symbolic link could be created (TRUE), or if the test failed (FALSE)
OUT_ERROR_MESSAGE
When the test fails, the variable named will be set to helpful error message with a suggestion for resolving the issue on Windows OSs. Otherwise, it will contain an empty string.
Examples¶
jcm_check_symlinks_available(
SUCCESS_CACHE
OUT_ERROR_MESSAGE symlink_err_message)
if(symlink_err_message)
message(WARNING "${symlink_err_message}")
else()
message(STATUS "yay!")
endif()
jcm_check_symlinks_cloned¶
- jcm_check_symlinks_cloned¶
jcm_check_symlinks_cloned( PATHS <path>... <[OUT_BROKEN_SYMLINK <out-var>] [OUT_ERROR_MESSAGE <out-var>] >)
Checks if all of the PATHS
refer to symbolic links. All of the paths must exist, or
the function will emit a fatal error. All relative paths will be converted to full-paths, based off
CMAKE_CURRENT_SOURCE_DIR
, which is necessary for the internal IS_SYMLINK
check.
As opposed to just using CMake’s IS_SYMLINK
check, this function provides a helpful error
message with a suggestion to fix the issue when using git. This function should primarily be used
when a project includes symbolic links checked into SCM, and you would like to check if the symbolic
links were properly cloned, which isn’t the default case with Windows+Git.
Parameters¶
One Value¶
OUT_BROKEN_SYMLINK
When a broken symlink exists, the variable named will be set to the absolute path of the broken symlink. Otherwise, the variable named will be set to an empty string
OUT_ERROR_MESSAGE
When a broken symlink exists, the variable named will be set to a helpful error message with a suggestion to fix the issue when using git. Otherwise, the variable named will be set to an empty string. The error message contains the path to the broken symlink, on failure.
Multi Value¶
PATHS
A list of relative or absolute paths to files or directories that will be checked to be symbolic links
Examples¶
jcm_check_symlinks_cloned(
OUT_BROKEN_SYMLINK broken_symlink
OUT_ERROR_MESSAGE warning_message
PATHS "data/image_to_read.png")
if(broken_symlink)
message(WARNING "Will not build 'test-image' test:\n" ${warning_message})
list(APPEND exclude_tests "test-image")
endif()
jcm_follow_symlinks¶
- jcm_follow_symlinks¶
jcm_follow_symlinks( PATHS <path>... <[OUT_VAR <out-var>] [OUT_NON_EXISTENT_INDICES <out-var>] >)
Converts the provided list of paths, PATHS
, into a list of absolute, normalized
paths with all symbolic link chains traced to their final files/directories. Care is taken for
multiple platforms, where symbolic links may contain paths with different path separators; all
symbolic links are converted to CMake paths (*nix separators). The target paths will be placed in
the variable named by OUT_VAR
, and will be in the same order as the paths provided
via PATHS
. When a non-symlink is provided, it will directly be placed in the
result.
The function checks for non-existent paths, including the provided path, intermediate symbolic links
, and the final target path. When one is reached, the associated result element is set to the
non-existent path, followed by -NOTFOUND (/home/test.js -> /home/test.js-NOTFOUND). These can
directly be placed in a CMake if
statement to check for existence. Furthermore, the
variable named by OUT_NON_EXISTENT_INDICES
will contain the indices of all
non-existent paths in PATHS
, and therefore the variable named by
OUT_VAR
.
Parameters¶
One Value¶
OUT_VAR
The variable named will be set to all the paths in
PATHS
, after being converted to normalized, absolute paths, with all symbolic link chains traced to their final files/directories. Paths are in the in the same order as they’re provided. See above for results for non-existent paths.OUT_NON_EXISTENT_INDICES
The variable named will be set to the indices of paths in
PATHS
which introduced a non-existent path.
Multi Value¶
PATHS
A list of relative or absolute paths, where any paths to symbolic link chains will be followed. All paths will be internally converted to absolute, normalized paths.
Examples¶
# real_file.txt exists, fake_file.txt does not
file(CREATE_LINK real_file.txt new_link.txt SYMBOLIC)
jcm_follow_symlinks(
PATHS real_file.txt new_link.txt fake_file.txt
OUT_VAR followed_links)
message(STATUS
"${followed_links} == "
"/home/here/real_file.txt;/home/here/real_file.txt;/home/here/fake_file.txt-NOTFOUND")
JcmArbitraryScript¶
In most cases, CMake will reconfigure as necessary to update targets and files when it detects changes. However, it’s sometimes necessary to enact some action as part of the project’s build phase as opposed to its configure phase. This is often achieved in multiple steps by first generating the desired script at configure time, and then creating targets with commands that invoke an interpreter on that script, like cmake -P …, bash, or python.
This module is designed to act as the generated script from configure time, but instead of containing specific code, it directly evaluates the CMake code provided in a command-line argument, thereby allowing it to evaluate any arbitrary CMake code. Executing cmake -P /path/to/JcmArbitraryScript.cmake – ‘<cmake code>’ provides behaviour equivalent to bash -c ‘<bash code>’ or node -e ‘<javascript code>’. Although this module was created with the intention of simplifying invocations of scripts in the generated buildsystem, it fundamentally allows cmake -P to accept code as a string instead of from a file.
Additionally provided in this module is jcm_form_arbitrary_script_command()
, which
allows easily and consistently creating a CMake command at configure-time to invoke arbitrary CMake
code at build-time by interpreting this file in script mode. That function should be the primary interface through which this module is
used. Examples of direct use follows. Note that escape sequences are interpreted by this script.
cmake -P /path/to/jgd-cmake-modules/JcmArbitraryScript.cmake --
'message("first\ command")\n\ message("second\ command")'
jcm_form_arbitrary_script_command¶
- jcm_form_arbitrary_script_command¶
jcm_form_arbitrary_script_command( OUT_VAR <out-var> CODE <cmake-code>...)
Forms a command that is suitable for use as a COMMAND
argument to functions such
as add_custom_command()
that will evaluate the provided CODE
when
executed. This is useful to invoke arbitrary code in the build-phase of a project without having to
generate intermediate script files or the commands to invoke interpreters on them.
Escape sequences in the CODE
strings will be preserved by escaping their backslash
and control characters will be escaped to become escape sequences. This ensures control characters
aren’t interpreted by CMake as it generates the buildsystem or the buildsystem itself, as these
would create malformed build files. Escape sequences are then interpreted by
JcmArbitraryScript.cmake to unwind the escaping introduced here.
Parameters¶
One Value¶
OUT_VAR
The variable named will be set to the resultant command that is suitable for use as a
COMMAND
argument to functions such asadd_custom_command()
. This will always be a semicolon separated list.
Multi Value¶
CODE
Collection of CMake code that will be joined and evaluated by CMake when the command is executed
Examples¶
# adapted from `jcm_create_message_target`_ to emit a message at build-time
set(log_level "WARNING")
set(message_text "hello")
list(APPEND message_text ", goodby")
jcm_form_arbitrary_script_command(
OUT_VAR message_command
CODE "message(${log_level}" "${messages})")
add_custom_target(build_time_message ALL COMMAND "${message_command}")
# a contrived example invoking JCM modules in a command at build-time
jcm_form_arbitrary_script_command(
OUT_VAR ensure_symlink_command
CODE [[
cmake_minimum_required(VERSION ${CMAKE_MINIMUM_REQUIRED_VERSION})
set(jgd-cmake-modules_DIR "${jgd-cmake-modules_DIR}")
find_package(jgd-cmake-modules CONFIG REQUIRED)
include(JcmSymlinks)
jcm_check_symlinks_available(OUT_ERROR_MESSAGE symlink_err_message)
if(symlink_err_message)
message(FATAL_ERROR "${symlink_err_message}")
endif()
]])
add_custom_target(do_configure
COMMAND "${ensure_symlink_command}"
COMMAND
"${CMAKE_COMMAND}" -E create_symlink
/usr/local/lib/node_modules /usr/local/lib/node_modules)