The usage steps of this template can be divided into
- Rename
- Configure
- Switch to developer mode
- Build
- Test
- Install
- A note for multi-config generators and LSP based on
compile_commands.json - Almost always use conan
Note that vcpkg can also be handled like configure option 1, see aminya/cpp_vcpkg_project.
In addition, the appendix gives a hint on almost-always-use-conan style usage.
Of course, you can use release conan packages in your debug configuration, see below.
First, rename all sample_project in file contents and file names to a project name you like. You can do this via the script rename.py in script.py folder:
python3 script/rename.py sample_project <new_project_name>You can also do this to the sample C++ executable, header-only library and library:
python3 script/rename.py sample_app <new_app_name>
python3 script/rename.py sample_header_only_lib <new_header_only_lib_name>
python3 script/rename.py sample_lib <new_lib_name>dirname(dirname(abspath(__file__))). DON'T move the script to somewhere else.
Edit CMakeLists.txt, add a line run_conan() between include(sample_project_fetch_project_options) and project(cpp_novice LANGUAGES CXX). That is:
cmake_minimum_required(VERSION 3.25)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(fix_msvc)
include(sample_project_options)
include(sample_project_fetch_project_options)
run_conan()
project(sample_project VERSION 0.0.1 LANGUAGES CXX)By adding this line of code, we enable cmake to use conan automatically, all we need to do is to configure cmake as usual. For example:
cmake -B build -S .See Conan Docs: Consuming packages for more help.
You can let conan try to guess the profile, based on the current operating system and installed tools:
conan profile detect --forceYou can set environment variables CC and CXX to help conan find the correct compilers, for example in bash:
export CC="clang"
export CXX="clang++"
conan profile detect --forceIn addition, in the conan/profiles folder, I've provided some generic profiles for you (and for CI). You can use script/match_conan_profile.py to find the best matching generic profile based on your query:
(See more details in conan/profiles/README.md.)
# "Usage: python3 script/match_conan_profile.py <conan_profile> (specified as <os>-<os_version>-<architecture>-<compiler>-<compiler_version>-<build_type>)"
python3 script/match_conan_profile.py "macos-#-armv8-clang-#-Debug" # `#` represents a wildcard characterHowever, it is highly recommended to write a conan profile manually instead of depending on the detected one. In the profile, you can set information like the operating system, compiler or build configuration.
For example, the following is my clang and gcc profile on MacOS m1: (see more in conan/profiles)
_common for common profile settings
[settings]
arch={{ detect_api.detect_arch() }}
os={{ detect_api.detect_os() }}
build_type=Release
benchmark/*:build_type=Release
boost/*:compiler.cppstd=20
[platform_tool_requires]
cmake/3.29.3
ninja/1.12.1
[conf]
# &: influence only the current package but not any depedencies
# see more in https://docs.conan.io/2/reference/config_files/profiles.html#profile-patterns
&:tools.cmake.cmaketoolchain:generator=Ninja Multi-Configclang profile
include(_common)
{% set compiler, version, compiler_exe = detect_api.detect_clang_compiler("clang") %}
[settings]
compiler={{ compiler }}
compiler.cppstd=26
compiler.libcxx={{ detect_api.detect_libcxx(compiler, version, compiler_exe) }}
compiler.version={{ detect_api.default_compiler_version(compiler, version) }}
[conf]
tools.build:compiler_executables = {"c": "{{ compiler_exe }}", "cpp": "{{ compiler_exe | replace("clang", "clang++") }}"}
tools.build:cflags=['-L/opt/homebrew/opt/llvm/lib/c++', '-Wno-unused-command-line-argument']
tools.build:cxxflags=['-L/opt/homebrew/opt/llvm/lib/c++', '-Wno-unused-command-line-argument']gcc profile
include(_common)
{% set compiler, version, compiler_exe = detect_api.detect_gcc_compiler("gcc-14") %}
[settings]
compiler={{ compiler }}
compiler.cppstd=23
compiler.libcxx={{ detect_api.detect_libcxx(compiler, version, compiler_exe) }}
compiler.version={{ detect_api.default_compiler_version(compiler, version) }}
scnlib/*:compiler.cppstd=20
[conf]
tools.build:compiler_executables = {"c": "{{ compiler_exe }}", "cpp": "{{ compiler_exe | replace("gcc", "g++") }}"}Use conan install -h for help.
To install conan dependencies:
conan install . -pr <profile> -b missingYou can add -s build_type=[Release|Debug|MinSizeRel|RelWithDebInfo] or other settings/configurations/options in the command line:
conan install . -pr <profile> -b missing -s build_type=ReleaseYou can specify more than one profiles, to merge the profile settings:
conan install . -pr _common -pr gcc -b missing -s build_type=ReleaseYou can specify build_type for some specific packages:
conan install . -pr _common -pr gcc -b missing -s build_type=Debug -s "opencv/*:build_type=Release" -s "&:build_type=Release"After this, conan will generate CMakeUserPresets.json for cmake.
Use cmake --help for help.
List all available configure presets:
cmake --list-presetsChoose one to configure (preset clang for instance):
cmake --preset clangBy default, cmake configures the project on user mode. For developers, you can switch to developer mode by:
cmake --preset clang -DENABLE_DEVELOPER_MODE:BOOL=ONcmake --preset clang
ccmake --preset clangTry it yourself.
Use cmake --build and conan build -h for help.
List all available build presets:
cmake --build --list-presetsChoose one to build (preset clang-debug for instance):
cmake --build --preset clang-debugList all available targets:
cmake --build --preset clang-debug -t helpThen build (targets app and test_app for instance):
cmake --build --preset clang-debug -t app test_appUse ctest --help for help.
List all available test presets:
ctest --list-presetsChoose one to test (preset clang-debug for instance):
ctest --preset clang-debugIf fails, run the failed test with coloured output:
ctest --preset clang-debug --rerun-failed --output-on-failurethe install prefix defaults to
/usr/localon UNIX andC:/Program Files/${PROJECT_NAME}on Windows
Reconfigure to specify the install prefix if hasn't:
cmake --preset clang --install-prefix <directory>Install:
cmake --build --preset clang-debug -t installUse cmake --install for help.
cmake --install <build_dir> [<options>]If you use CMake with multi-config generators (like Ninja Multi-Config, XCode, Visual Studio) and a LSP based on compile_commands.json (like clangd, Qt Creator, CLion), please make sure to define CMAKE_CONFIGURATION_TYPES yourself and install conan packages for all configuration types.
For example, if you're setting cmake <other args> "-DCMAKE_CONFIGURATION_TYPES=Release;Debug", you should install conan packages for both Release and Debug configuration types.
Why? When using cmake with multi-config-generators, cmake merges compile flags in all configuration types into a single compile_commands.json file, and this project template uses Release;Debug;RelWithDebInfo;MinSizeRel by default. If you only install conan packages for Release configuration, your LSP may be confused: while your Release configuration includes conan packages installed, your compile flags in Debug/RelWithDebInfo/MinSizeRel configurations includes nothing!
Of course, you could use Release conan packages in Debug/RelWithDebInfo/MinSizeRel conan packages, or vice versa. See here.
See Conan Docs: Creating packages and Conan Docs: Developing packages locally for more help.
You can make use of conan commands to simplify CI and so on.
- install dependencies:
conan install <args> - install dependencies and build:
conan build <args> -c tools.build:skip_test=True - install dependencies, build and test:
conan build <args> - install, build, test and package project:
conan create <args> - pacakge built project:
conan export-pkg <args>⚠️ Not working, you need to writepacakge()andpacakge_id()methods in conanfile.py