### Installing a CMake Project Source: https://cliutils.gitlab.io/modern-cmake/chapters/intro/running.html These commands demonstrate how to install a CMake project. Choose the command appropriate for your current directory (build or source) and CMake version. ```bash # From the build directory (pick one) ~/package/build $ make install ~/package/build $ cmake --build . --target install ~/package/build $ cmake --install . # CMake 3.15+ only ``` ```bash # From the source directory (pick one) ~/package $ make -C build install ~/package $ cmake --build build --target install ~/package $ cmake --install build # CMake 3.15+ only ``` -------------------------------- ### Configure and Install Package Files Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/install/installing.md Configures the `MyLibConfig.cmake` file using a template and installs both the main configuration file and the version configuration file. ```cmake configure_file(MyLibConfig.cmake.in MyLibConfig.cmake @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/MyLibConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/MyLibConfigVersion.cmake" DESTINATION lib/cmake/MyLib ) ``` -------------------------------- ### Installing a Project (from source directory) Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/running.md Commands to install a CMake project when run from the source directory. These commands specify the build directory as an argument. ```bash make -C build install ``` ```bash cmake --build build --target install ``` ```bash cmake --install build ``` -------------------------------- ### DictExample.cxx Implementation Source: https://cliutils.gitlab.io/modern-cmake/_sources/examples/root-dict/README.md This C++ source file provides the implementation for the dictionary example class. It contains a simple method. ```cpp #include "DictExample.h" void DictExample::process() { // Do something } ``` -------------------------------- ### Manual Option Setup Equivalent to CMakeDependentOption Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/features/modules.md This demonstrates the manual setup that CMakeDependentOption abstracts, showing how to conditionally set an option based on other variables. ```cmake if(VAL1 AND VAL2) set(BUILD_TESTS_DEFAULT ON) else() set(BUILD_TESTS_DEFAULT OFF) endif() option(BUILD_TESTS "Build your tests" ${BUILD_TESTS_DEFAULT}) if(NOT BUILD_TESTS_DEFAULT) mark_as_advanced(BUILD_TESTS) endif() ``` -------------------------------- ### Installing a Project (from build directory) Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/running.md Commands to install a CMake project when run from the build directory. Choose one command based on your CMake version and preference. ```bash make install ``` ```bash cmake --build . --target install ``` ```bash cmake --install . ``` -------------------------------- ### SimpleExample.cxx for ROOT Project Source: https://cliutils.gitlab.io/modern-cmake/_sources/examples/root-usefile/README.md A basic C++ source file for a ROOT project. This example demonstrates minimal ROOT integration, typically used with the UseFile system. ```cpp #include int main() { std::cout << "Hello from SimpleExample!\n"; return 0; } ``` -------------------------------- ### Install CMake to ~/.local on Linux Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/installing.md Installs CMake to the user's local directory using wget and tar. Ensure wget is available or substitute with curl. ```bash ~ $ wget -qO- "https://cmake.org/files/v4.1/cmake-4.1.3-linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C ~/.local ``` -------------------------------- ### Generate Header File at Build Time with Python Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/basics/programs.md Use `add_custom_command` to execute a script during the build process. This example generates a header file using a Python script. It depends on `some_target` and is made available via `add_custom_target` and `install`. ```cmake find_package(PythonInterp REQUIRED) add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp" COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/GenerateHeader.py" --argument DEPENDS some_target) add_custom_target(generate_header ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp DESTINATION include) ``` -------------------------------- ### Install CMake using Pip Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/installing.md Use this command to install the CMake package if you have pip (Python's package installer) and a binary exists for your system. This respects your current virtual environment. ```bash pip install cmake ``` -------------------------------- ### Example Project Directory Structure Source: https://cliutils.gitlab.io/modern-cmake/chapters/basics/structure.html A typical layout for a CMake project including library, application, and test components. ```text - project - .gitignore - README.md - LICENSE.md - CMakeLists.txt - cmake - FindSomeLib.cmake - something_else.cmake - include - project - lib.hpp - src - CMakeLists.txt - lib.cpp - apps - CMakeLists.txt - app.cpp - tests - CMakeLists.txt - testlib.cpp - docs - CMakeLists.txt - extern - googletest - scripts - helper.py ``` -------------------------------- ### Install Project with CMake Source: https://cliutils.gitlab.io/modern-cmake/chapters/intro/newcmake.html Use `cmake --install` to install the project without invoking the build system directly. This command was introduced in CMake 3.15. ```bash cmake . --install ``` -------------------------------- ### Install Exported Targets File Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/install/installing.md Installs an exported targets file, which lists the targets to be made available to consumers of the package. Use `NAMESPACE` to avoid name collisions. ```cmake install(EXPORT MyLibTargets FILE MyLibTargets.cmake NAMESPACE MyLib:: DESTINATION lib/cmake/MyLib ) ``` -------------------------------- ### System-wide CMake install in Docker Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/installing.md Installs CMake to /usr/local, suitable for Docker containers or system-wide installations. This command uses wget and tar. ```bash docker $ wget -qO- "https://cmake.org/files/v4.1/cmake-4.1.3-linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local ``` -------------------------------- ### CMakeLists.txt: Basic Library and Executable Setup Source: https://cliutils.gitlab.io/modern-cmake/chapters/basics/example.html This snippet defines a CMake project with a static library and an executable, linking the executable to the library. It's suitable for simple projects requiring a single library and application. ```cmake # Almost all CMake files should start with this # You should always specify a range with the newest # and oldest tested versions of CMake. This will ensure # you pick up the best policies. cmake_minimum_required(VERSION 3.15...4.1) # This is your project statement. You should always list languages; # Listing the version is nice here since it sets lots of useful variables project( ModernCMakeExample VERSION 1.0 LANGUAGES CXX) # If you set any CMAKE_ variables, that can go here. # (But usually don't do this, except maybe for C++ standard) # Find packages go here. # You should usually split this into folders, but this is a simple example # This is a "default" library, and will match the *** variable setting. # Other common choices are STATIC, SHARED, and MODULE # Including header files here helps IDEs but is not required. # Output libname matches target name, with the usual extensions on your system add_library(MyLibExample simple_lib.cpp simple_lib.hpp) # Link each target with other targets or add options, etc. # Adding something we can run - Output name matches target name add_executable(MyExample simple_example.cpp) # Make sure you link your targets with this command. It can also link libraries and # even flags, so linking a target that does not exist will not give a configure-time error. target_link_libraries(MyExample PRIVATE MyLibExample) ``` -------------------------------- ### Install CMake to a local folder and add to PATH Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/installing.md Creates a local directory for CMake, downloads and extracts it, then sets the PATH environment variable for the current session. Append this to your shell's startup file for persistence. ```bash ~ $ mkdir -p cmake-4.1 && wget -qO- "https://cmake.org/files/v4.1/cmake-4.1.3-linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C cmake-4.1 ~ $ export PATH=`pwd`/cmake-4.1/bin:$PATH ``` -------------------------------- ### Set CMake Install Prefix Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/running.md Specify the installation directory using -DCMAKE_INSTALL_PREFIX. Defaults to /usr/local on UNIX systems. ```bash -DCMAKE_INSTALL_PREFIX= ``` -------------------------------- ### Simple CMake Project Configuration Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/basics/example.md This CMakeLists.txt defines a simple project with one library and one application. It includes setup for a library (MyLibExample) with its header and source files, and an application (MyExample) with its source file. Ensure the files are structured correctly within the project directory. ```cmake cmake_minimum_required(VERSION 3.10) project(SimpleProjectExample VERSION 1.0) # Library add_library(MyLibExample src/my_lib_example.cpp include/my_lib_example.h) target_include_directories(MyLibExample PUBLIC include) # Application add_executable(MyExample src/my_example.cpp) target_link_libraries(MyExample PRIVATE MyLibExample) ``` -------------------------------- ### Install Library Targets Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/install/installing.md Installs library targets, including runtime libraries, archives, and executables, to their respective destinations. Also sets the include directory for exported targets. ```cmake install(TARGETS MyLib EXPORT MyLibTargets LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin INCLUDES DESTINATION include ) ``` -------------------------------- ### Simple C++ Example for ROOT Source: https://cliutils.gitlab.io/modern-cmake/examples/root-simple/README.html A basic C++ program that utilizes ROOT's TLorentzVector. Ensure ROOT is configured in your CMakeLists.txt to compile this. ```cpp #include int main() { TLorentzVector v(1,2,3,4); v.Print(); return 0; } ``` -------------------------------- ### Find and Link Boost::filesystem Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/packages/Boost.md This example finds the Boost library with the 'filesystem' component and links it to your target. It includes a conditional block to define the `Boost::filesystem` imported target if it doesn't exist, which is necessary for older CMake versions or when Boost is newer than CMake. ```cmake set(Boost_USE_STATIC_LIBS OFF) set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) find_package(Boost 1.50 REQUIRED COMPONENTS filesystem) message(STATUS "Boost version: ${Boost_VERSION}") # This is needed if your Boost version is newer than your CMake version # or if you have an old version of CMake (<3.5) if(NOT TARGET Boost::filesystem) add_library(Boost::filesystem IMPORTED INTERFACE) set_property(TARGET Boost::filesystem PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIR}) set_property(TARGET Boost::filesystem PROPERTY INTERFACE_LINK_LIBRARIES ${Boost_LIBRARIES}) endif() target_link_libraries(MyExeOrLibrary PUBLIC Boost::filesystem) ``` -------------------------------- ### CMakeLists.txt for ROOT Project Source: https://cliutils.gitlab.io/modern-cmake/_sources/examples/root-usefile/README.md This CMakeLists.txt file configures a ROOT project using the UseFile system. It's designed for minimal setups without generating a dictionary. ```cmake # Minimal CMakeLists.txt for a ROOT project using UseFile cmake_minimum_required(VERSION 3.16) project("SimpleROOTProject" LANGUAGES CXX) find_package(ROOT REQUIRED COMPONENTS Core) # Use the UseFile system for ROOT root_use_file(${PROJECT_NAME}) add_executable(SimpleExample SimpleExample.cxx) target_link_libraries(SimpleExample PRIVATE PRIVATE ROOT::Core) ``` -------------------------------- ### Enable Interprocedural Optimization with CMake Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/features/small.md This example shows how to enable interprocedural optimization (IPO) for a target using CMake 3.9+. It first checks for IPO support using the CheckIPOSupported module. ```cmake include(CheckIPOSupported) check_ipo_supported(RESULT result) if(result) set_target_properties(foo PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) endif() ``` -------------------------------- ### Add a Test with Specific Libraries Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/testing/googletest.md Example usage of `package_add_test_with_libraries` to create a test 'test1' linking 'lib_to_test' and setting a specific working directory. ```cmake package_add_test_with_libraries(test1 test1.cpp lib_to_test "${PROJECT_DIR}/european-test-data/") ``` -------------------------------- ### CMakeLists.txt for ROOT Project Source: https://cliutils.gitlab.io/modern-cmake/examples/root-usefile/README.html Configure a CMake project to use ROOT. Ensure ROOT 6.16 or later is installed and findable. The `ROOT_USE_FILE` includes global settings, and linker flags are handled for compatibility. ```cmake cmake_minimum_required(VERSION 3.15...4.1) project(RootUseFileExample LANGUAGES CXX) find_package(ROOT 6.16 CONFIG REQUIRED) ## [core] # Sets up global settings include("${ROOT_USE_FILE}") # This is required for ROOT < 6.16 # string(REPLACE "-L " "-L" ROOT_EXE_LINKER_FLAGS "${ROOT_EXE_LINKER_FLAGS}") # This is required on if there is more than one flag (like on macOS) separate_arguments(ROOT_EXE_LINKER_FLAGS) add_executable(RootUseFileExample SimpleExample.cxx) target_link_libraries(RootUseFileExample PUBLIC ${ROOT_LIBRARIES} ${ROOT_EXE_LINKER_FLAGS}) ``` -------------------------------- ### Format Code with Clang-Format Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/features/utilities.md Manually format C++ source and header files using clang-format. This example uses git ls-files to find relevant files and xargs to apply formatting in-place. ```bash $ git ls-files -- '*.cpp' '*.h' | xargs clang-format -i -style=file $ git diff --exit-code --color ``` -------------------------------- ### Create Symbolic Link with CMake Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/newcmake.md Use `file(CREATE_SYMLINK ...)` to create symbolic links. Supported on Windows starting from CMake 3.13. ```cmake file(CREATE_SYMLINK target link_name [follow_symlink]) ``` -------------------------------- ### Simple C++ Class Implementation Source: https://cliutils.gitlab.io/modern-cmake/examples/root-dict/README.html Provides the implementation for a simple C++ class with a method to return a double value. This is a supporting file for the dictionary generation example. ```cpp #include "DictExample.h" Double_t Simple::GetX() const {return x;} ClassImp(Simple) ``` -------------------------------- ### Simple C++ Example for ROOT Source: https://cliutils.gitlab.io/modern-cmake/examples/root-usefile/README.html A basic C++ program that utilizes ROOT's `TLorentzVector` class. This snippet demonstrates creating and printing a `TLorentzVector` object. ```cpp #include int main() { TLorentzVector v(1,2,3,4); v.Print(); return 0; } ``` -------------------------------- ### Configure Version Header with CMake Source: https://cliutils.gitlab.io/modern-cmake/chapters/basics/comms.html Use the `configure_file` command in CMake to process a version header template (`.in` file) and generate the final header file in the build directory. Include the binary include directory in your build setup. ```cmake configure_file ( "${PROJECT_SOURCE_DIR}/include/My/Version.h.in" "${PROJECT_BINARY_DIR}/include/My/Version.h" ) ``` -------------------------------- ### SimpleExample.cxx for ROOT Project Source: https://cliutils.gitlab.io/modern-cmake/_sources/examples/root-simple/README.md This C++ source file contains the main function for the ROOT project. It includes the necessary ROOT headers and demonstrates basic usage. ```cpp #include int main() { std::cout << "Hello from SimpleROOTProject!\n"; return 0; } ``` -------------------------------- ### Get File Size with CMake File Command Source: https://cliutils.gitlab.io/modern-cmake/chapters/intro/newcmake.html Use `SIZE` with the `FILE` command in CMake 3.14 to get the size of a file in bytes. ```cmake file(SIZE filename size_variable) ``` -------------------------------- ### Create C++11 Library and Executable Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/basics.md Sets up a C++11 library and an executable that links to it, specifying minimum CMake version and project language. ```cmake cmake_minimum_required(VERSION 3.15...4.1) project(Calculator LANGUAGES CXX) add_library(calclib STATIC src/calclib.cpp include/calc/lib.hpp) target_include_directories(calclib PUBLIC include) target_compile_features(calclib PUBLIC cxx_std_11) add_executable(calc apps/calc.cpp) target_link_libraries(calc PUBLIC calclib) ``` -------------------------------- ### Build Minuit2 Standalone with CMake Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/packages/Minuit2.md Shows how to configure the build for a standalone Minuit2 distribution using CMake, copying necessary files into the source directory. ```bash # Copies files into source directory cmake /root/math/minuit2 -Dminuit2-standalone=ON ``` -------------------------------- ### Link Minuit2 with CMake Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/packages/Minuit2.md Demonstrates how to add Minuit2 as a subdirectory or find it using find_package and link it to your program. ```cmake add_subdirectory(minuit2) # or root/math/minuit2 # OR find_package(Minuit2 CONFIG) # Either build or install target_link_libraries(MyProgram PRIVATE Minuit2::Minuit2) ``` -------------------------------- ### Conditional include directories with generator expressions Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/basics/functions.md Manage include directories differently for build and install targets using generator expressions. This is a common pattern for packages supporting installation. ```cmake target_include_directories( MyTarget PUBLIC $ $ ) ``` -------------------------------- ### Add local bin to PATH Source: https://cliutils.gitlab.io/modern-cmake/chapters/intro/installing.html Add this export command to your .bashrc, .bash_profile, or .profile file to ensure that executables installed to ~/.local/bin are available in your PATH. This is useful when installing packages with a CMAKE_INSTALL_PREFIX of ~/.local. ```bash export PATH="$HOME/.local/bin:$PATH" ``` -------------------------------- ### Use ROOT's CMake Use File (Old Method) Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/packages/ROOT.md This method uses ROOT's provided CMake utility file to set up global variables and include directories. It's simpler for basic scripts but can be problematic for complex projects. You still need to manually link libraries. ```cmake include(${ROOT_USE_FILE}) # For older versions, you might need to manually link libraries and flags # target_link_libraries(my_app PRIVATE ${ROOT_LIBRARIES} ${ROOT_EXE_LINKER_FLAGS}) # Note: ROOT_EXE_LINKER_FLAGS may need separate_arguments ``` -------------------------------- ### Fetch and Populate Catch2 (CMake 3.11+) Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/projects/fetch.md For CMake versions prior to 3.14, use FetchContent_GetProperties to check if the content is populated, FetchContent_Populate to download it if necessary, and add_subdirectory to integrate it. This method requires manual checking and population. ```cmake # CMake 3.11+ FetchContent_GetProperties(catch) if(NOT catch_POPULATED) FetchContent_Populate(catch) add_subdirectory(${catch_SOURCE_DIR} ${catch_BINARY_DIR}) endif() ``` -------------------------------- ### Get Target Property Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/basics/variables.md Retrieve the value of a property attached to a target using the `get_property` command. The result is stored in a specified variable. ```cmake get_property(ResultVariable TARGET TargetName PROPERTY CXX_STANDARD) ``` -------------------------------- ### Get Filename Component with Last Extension Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/newcmake.md Use `get_filename_component` with `LAST_EXT` to extract the last extension from a filename. This is useful for parsing versioned filenames. ```cmake get_filename_component(EXT "version.1.2.zip" LAST_EXT) ``` -------------------------------- ### Fetch GoogleTest using FetchContent Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/testing/googletest.md Use FetchContent to declare, download, and add the GoogleTest library to your project. Ensure the content is populated only once. ```cmake include(FetchContent) FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.8.0 ) FetchContent_GetProperties(googletest) if(NOT googletest_POPULATED) FetchContent_Populate(googletest) add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR}) endif() ``` -------------------------------- ### Add Include Directory to Target Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/basics.md Adds a specified include directory to a target. PUBLIC ensures dependencies also get this include directory. ```cmake target_include_directories(one PUBLIC include) ``` -------------------------------- ### CMakeLists.txt for ROOT Project Source: https://cliutils.gitlab.io/modern-cmake/_sources/examples/root-simple/README.md This CMakeLists.txt file configures a basic ROOT project. It specifies the project name and includes necessary ROOT components. ```cmake cmake_minimum_required(VERSION 3.16) project("SimpleROOTProject" LANGUAGES CXX) find_package(ROOT REQUIRED COMPONENTS Core) add_executable(simple_root_example SimpleExample.cxx) target_link_libraries(simple_root_example PRIVATE ROOT::Core) ``` -------------------------------- ### FetchContent at Configure Time Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/newcmake.md The `FetchContent` module now allows downloads to occur at configure time, simplifying dependency handling. Available since CMake 3.11. ```cmake include(FetchContent) FetchContent_Declare(MyDependency GIT_REPOSITORY https://github.com/user/myrepo.git ) FetchContent_MakeAvailable(MyDependency) ``` -------------------------------- ### Package Minuit2 Source Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/packages/Minuit2.md Command to create a .tar.gz source package from the Minuit2 source directory. ```bash # Makes .tar.gz from source directory make package_source ``` -------------------------------- ### Get Git Version Number with CMake Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/projects/submodule.md Execute a Git command to retrieve the short commit hash and store it in a CMake variable. This is useful for versioning. ```cmake execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE PACKAGE_GIT_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) ``` -------------------------------- ### CMake If Statement Example Source: https://cliutils.gitlab.io/modern-cmake/chapters/basics/functions.html Demonstrates a basic CMake if statement for checking variable truthiness. Handles cases where variables are ON, YES, TRUE, or non-zero numbers. ```cmake if(variable) # If variable is `ON`, `YES`, `TRUE`, `Y`, or non zero number else() # If variable is `0`, `OFF`, `NO`, `FALSE`, `N`, `IGNORE`, `NOTFOUND`, `""`, or ends in `-NOTFOUND` endif() # If variable does not expand to one of the above, CMake will expand it then try again ``` -------------------------------- ### Trace CMake Configuration Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/running.md Use the --trace option to print every line of CMake executed during the configure process. This is very verbose. ```bash --trace ``` -------------------------------- ### Add a Test Using the Custom Macro Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/testing/googletest.md Example usage of the `package_add_test` macro to define a test executable named 'test1' with source file 'test1.cpp'. ```cmake package_add_test(test1 test1.cpp) ``` -------------------------------- ### Link CUDA Library with find_package(CUDAToolkit) Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/packages/CUDA.md Example of finding the CUDAToolkit and linking a CUDA library. This modern approach uses `find_package(CUDAToolkit)` and `target_link_libraries`. ```cmake cmake_minimum_required(VERSION 3.17) project(example LANGUAGES CXX) find_package(CUDAToolkit REQUIRED) add_executable(uses_cublas source.cpp) target_link_libraries(uses_cublas PRIVATE CUDA::cublas) ``` -------------------------------- ### Setting CMake Options Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/running.md Use the -D flag to set CMake options. Use -L or -LH to list available options with or without descriptions. ```bash cmake -DOPTION_NAME=VALUE .. cmap -L . cmap -LH . ``` -------------------------------- ### Process Include-What-You-Use Output Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/features/utilities.md Collect the output from the build process that uses include-what-you-use and pipe it to the fix_includes.py script to apply suggested changes. Always review the fixes. ```bash ~/package # cmake --build build-iwyu 2> iwyu.out ~/package # fix_includes.py < iwyu.out ``` -------------------------------- ### Register a Simple Test Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/testing.md Register a test with a given name and specify the executable target to run. Any string after COMMAND that is not a target name will be treated as a command line to execute. ```cmake add_test(NAME TestName COMMAND TargetName) ``` -------------------------------- ### Classic CMake Build Procedure Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/running.md Use this standard procedure for building CMake projects. Always create a separate build directory to avoid overwriting source files. ```bash mkdir build cd build cmake .. make ``` -------------------------------- ### Test Macro for ROOT Dictionary Loading Source: https://cliutils.gitlab.io/modern-cmake/examples/root-dict/README.html A C++ macro that loads the generated dictionary library, creates an instance of the `Simple` class, prints its value, saves it to a ROOT file, and retrieves it. ```cpp { gSystem->Load("libDictExample"); Simple s; cout << s.GetX() << endl; TFile *_file = TFile::Open("tmp.root", "RECREATE"); gDirectory->WriteObject(&s, "MyS"); Simple *MyS = nullptr; gDirectory->GetObject("MyS", MyS); cout << MyS->GetX() << endl; _file->Close(); } ``` -------------------------------- ### Add INTERFACE Targets to IMPORTED Libraries Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/newcmake.md Starting with CMake 3.11, you can directly add INTERFACE targets to IMPORTED INTERFACE libraries, simplifying dependency management. ```cmake add_library(MyLib::Interface INTERFACE IMPORTED) ``` -------------------------------- ### Run CMake with Pipx Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/installing.md Execute CMake in a disposable virtual environment without setup using pipx. This is particularly useful for CI/CD environments like GitHub Actions. ```bash pipx run cmake ``` -------------------------------- ### Register Test Using Generator Expression Source: https://cliutils.gitlab.io/modern-cmake/chapters/testing.html Register a test that executes the built target executable. This uses a generator expression to get the target's output location. ```cmake add_test(NAME TestName COMMAND $) ``` -------------------------------- ### Workflow Presets in CMake Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/newcmake.md Simplified command `cmake --workflow ` is now supported for managing workflow presets. ```bash cmake --workflow ``` -------------------------------- ### Verbose Builds with Make Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/running.md Enable verbose output when using Make as the build tool. This is a feature of Make itself. ```bash VERBOSE=1 make ``` -------------------------------- ### Target Sources Relative Path Handling Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/newcmake.md Starting with CMake 3.13 (policy CMP0076), `target_sources` correctly handles relative paths relative to the current source directory. ```cmake target_sources(myTarget PRIVATE src/main.cpp) ``` -------------------------------- ### Find ROOT Package in CMake Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/packages/ROOT.md Use this command to find the ROOT package in your CMake project. Ensure your ROOT installation paths are correctly set up, or use the -DROOT_DIR option. ```cmake find_package(ROOT REQUIRED) ``` -------------------------------- ### Standardize Library Usage with ALIAS Target Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/install.md Use an ALIAS target to standardize the usage of your library across different installation methods. This ensures consistency when your library is included as a subproject. ```cmake add_library(MyLib::MyLib ALIAS MyLib) ``` -------------------------------- ### Listing Available CMake Generators Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/running.md Run this command to see all the build tools (generators) that CMake can use on your system. ```bash cmake --help ``` -------------------------------- ### Create Symbolic Link on Windows Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/newcmake.md Use `-E create_symlink` with the `cmake --E` command to create symbolic links. This functionality is supported on Windows starting from CMake 3.13. ```bash cmake -E create_symlink target link_name ``` -------------------------------- ### Configure ROOT Project with CMake Source: https://cliutils.gitlab.io/modern-cmake/examples/root-simple/README.html Use this CMakeLists.txt to configure a ROOT project. It finds the ROOT package and links the executable to ROOT::Physics. ```cmake cmake_minimum_required(VERSION 3.15...4.1) project(RootSimpleExample LANGUAGES CXX) # Finding the ROOT package ## [find_package] find_package(ROOT 6.16 CONFIG REQUIRED) ## [find_package] # Adding an executable program and linking to needed ROOT libraries ## [add_and_link] add_executable(RootSimpleExample SimpleExample.cxx) target_link_libraries(RootSimpleExample PUBLIC ROOT::Physics) ## [add_and_link] ``` -------------------------------- ### Build Multiple Targets in CMake Source: https://cliutils.gitlab.io/modern-cmake/chapters/intro/newcmake.html The `cmake --build` command supports specifying multiple targets to build, as shown in this example for targets 'a' and 'b'. Available since CMake 3.15. ```bash cmake . --build --target a b ``` -------------------------------- ### Configure Source Package Variables in CMake Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/install/packaging.md Define generators for source packages and specify files to ignore to prevent bundling unnecessary content. This setup is crucial for creating clean source distributions. ```cmake set(CPACK_SOURCE_GENERATOR "TGZ;ZIP") set(CPACK_SOURCE_IGNORE_FILES /.git /dist /.*build.* /\\.DS_Store ) ``` -------------------------------- ### Picking a Compiler with CMake Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/intro/running.md Set the CC and CXX environment variables to specify the compiler for CMake. This is typically done only on the first CMake run in an empty directory. ```bash CC=clang CXX=clang++ cmake .. ``` -------------------------------- ### Download Catch2 Header with CMake Source: https://cliutils.gitlab.io/modern-cmake/chapters/testing/catch.html This snippet downloads the Catch2 header file using CMake's file() command. It includes error handling for the download process and sets up include directories. Ensure the URL and SHA256 hash are up-to-date for the desired Catch2 version. ```cmake add_library(catch_main main.cpp) target_include_directories(catch_main PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") set(url https://github.com/philsquared/Catch/releases/download/v2.13.6/catch.hpp) file( DOWNLOAD ${url} "${CMAKE_CURRENT_BINARY_DIR}/catch.hpp" STATUS status EXPECTED_HASH SHA256=681e7505a50887c9085539e5135794fc8f66d8e5de28eadf13a30978627b0f47) list(GET status 0 error) if(error) message(FATAL_ERROR "Could not download ${url}") endif() target_include_directories(catch_main PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") ``` -------------------------------- ### Download Catch2 Header with CMake Source: https://cliutils.gitlab.io/modern-cmake/_sources/chapters/testing/catch.md Use FetchContent to download the Catch2 header file. Ensure the download is successful before proceeding. This method is suitable for older CMake versions. ```cmake add_library(catch_main main.cpp) target_include_directories(catch_main PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") set(url https://github.com/philsquared/Catch/releases/download/v2.13.6/catch.hpp) file( DOWNLOAD ${url} "${CMAKE_CURRENT_BINARY_DIR}/catch.hpp" STATUS status EXPECTED_HASH SHA256=681e7505a50887c9085539e5135794fc8f66d8e5de28eadf13a30978627b0f47) list(GET status 0 error) if(error) message(FATAL_ERROR "Could not download ${url}") endif() target_include_directories(catch_main PUBLIC "${CMAKE_CURRENT_BINARY_DIR}") ``` -------------------------------- ### Get Git Version Number in CMake Source: https://cliutils.gitlab.io/modern-cmake/chapters/projects/submodule.html This CMake snippet executes 'git rev-parse --short HEAD' to retrieve the short commit hash of the current HEAD. It's useful for versioning your package. ```cmake execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE PACKAGE_GIT_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) ```