2.dos_donts
CMake dos and don'ts
Don'ts
-
Avoid Global Functions:
- Example: Do not use global functions like
link_directoriesorinclude_libraries. Instead, prefer defining and using CMake targets.
- Example: Do not use global functions like
-
Avoid Unnecessary PUBLIC Requirements:
- Example: Don’t force options like
-Wallon users by adding it to the PUBLIC interface of a target. Instead, use PRIVATE to ensure it’s not exposed to the users of your library.
- Example: Don’t force options like
-
Do Not GLOB Files:
- Example: Avoid using
file(GLOB ...)to include source files in your project. Instead, list them explicitly. Tools like Make won’t detect new files unless CMake is re-run. While CMake 3.12'sCONFIGURE_DEPENDSflag can help, it's better to avoid GLOB where possible.
- Example: Avoid using
-
Don't Link Directly to Built Files:
- Example: Instead of linking directly to a file like
target_link_libraries(MyApp /path/to/libmylib.a), always link to CMake targets, e.g.,target_link_libraries(MyApp mylib).
- Example: Instead of linking directly to a file like
-
Don't Skip PUBLIC/PRIVATE in Linking:
- Example: If you write
target_link_libraries(MyLib MyDep), it defaults to keyword-less, which can cause issues. Always specify whether the dependency is PUBLIC or PRIVATE.
- Example: If you write
Do's
-
Treat CMake as Code:
- Example: Organize your CMake files clearly, with comments and consistent formatting, just as you would with other programming languages.
-
Think in Targets:
- Example: Use targets to represent logical components of your application, such as creating
IMPORTEDorINTERFACEtargets for libraries that are used but not built by your project.
- Example: Use targets to represent logical components of your application, such as creating
-
Export Your Interface:
- Example: Ensure that your library can be used correctly from both the build stage and after installation by exporting its interface properly.
-
Write a config.cmake File:
- Example: This file should define how to find and use your library, making it easier for others to include your library in their projects.
-
Use ALIAS Targets:
- Example: Use
add_library(mylib ALIAS mylib_real)to maintain consistency betweenadd_subdirectoryandfind_package.
- Example: Use
-
Group Common Functionality:
- Example: If you have repeated tasks in your CMake scripts, encapsulate them in functions or macros. Prefer using functions for better scoping.
-
Use Lowercase for Function Names:
- Example: Always define your functions in lowercase like
function my_function(). Reserve uppercase for variables.
- Example: Always define your functions in lowercase like
-
Use cmake_policy or Version Ranges:
- Example: Regularly check and apply the latest policies by using
cmake_policy(SET CMP0074 NEW)unless you need to revert for compatibility.
- Example: Regularly check and apply the latest policies by using
-
Set an Appropriate Minimum Version:
- Example: Ensure your CMake version is at least as new as the oldest compiler version you plan to support by adding
cmake_minimum_required(VERSION 3.12)at the top of your CMakeLists.txt file.
- Example: Ensure your CMake version is at least as new as the oldest compiler version you plan to support by adding