UNPKG

@micro-os-plus/build-helper

Version:

A source library xPack to assist the µOS++ builds

161 lines (104 loc) 4.63 kB
# CMake Tips and tricks Extracts from Craig Scott's "Professional CMake - A Practical Guide". ## Folders ### CMAKE_SOURCE_DIR The top-most directory of the source tree (i.e. where the top-most CMakeLists.txt file resides). This variable never changes its value. - <https://cmake.org/cmake/help/latest/variable/CMAKE_SOURCE_DIR.html> ### CMAKE_CURRENT_SOURCE_DIR Note: use CMAKE_CURRENT_LIST_DIR. The directory of the CMakeLists.txt file currently being processed by CMake. It is updated each time a new file is processed as a result of an add_subdirectory() call and is restored back again when processing of that directory is complete. - <https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_SOURCE_DIR.html> ### CMAKE_CURRENT_LIST_DIR Analogous to CMAKE_CURRENT_SOURCE_DIR except it will be updated when processing the included file. This is the variable to use where the directory of the current file being processed is required, no matter how it has been added to the build. It will always hold an absolute path. The CMAKE_CURRENT_LIST_DIR variable is generally going to be a better choice than CMAKE_CURRENT_SOURCE_DIR. - <https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_LIST_DIR.html> ### CMAKE_CURRENT_LIST_FILE Always gives the name of the file currently being processed. It always holds an absolute path to the file, not just the file name. ### CMAKE_CURRENT_FUNCTION_LIST_DIR When executing code inside a function(), this variable contains the full directory of the listfile that defined the current function. - <https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.html> ## Other ### TARGET_FILE This will yield the absolute path and file name of the target’s binary, including any file prefix and suffix if relevant for the platform (e.g .exe, .dylib). For Unix-based platforms where shared libraries typically have version details in their file name, these will also be included. ### TARGET_FILE_NAME Same as TARGET_FILE but without the path (i.e. it provides just the file name part). ### TARGET_FILE_DIR Same as TARGET_FILE but without the file name. This is the most robust way to obtain the directory in which the final executable or library is built. It’s value is different for different build configurations when using a multi configuration generator like Xcode or Visual Studio. ## Generator expressions ### `$<CONFIG>` Evaluates to the build type. Use this in preference to the CMAKE_BUILD_TYPE variable since that variable is not used on multi configuration project generators like Xcode or Visual Studio. ### `$<PLATFORM_ID>` Identifies the platform for which the target is being built. This can be useful in cross-compiling situations, especially where a build may support multiple platforms (e.g. device and simulator builds). This generator expression is closely related to the CMAKE_SYSTEM_NAME variable and projects should consider whether using that variable would be simpler in their specific situation. ### `$<LOWER_CASE:...>`, `$<UPPER_CASE:...>` Any content can be converted to lower or upper case via these expressions. ### Language specific options ```cmake $<$<COMPILE_LANGUAGE:C>:-Wbad-function-cast> $<$<COMPILE_LANGUAGE:CXX>:-Wnoexcept> ``` ### Toolchain specific options ```cmake $<$<C_COMPILER_ID:GNU,Clang,AppleClang>:-ffunction-sections> $<$<C_COMPILER_ID:GNU,Clang,AppleClang>:-fdata-sections> $<$<C_COMPILER_ID:GNU>:"-Wl,--gc-sections"> $<$<C_COMPILER_ID:Clang,AppleClang>:"-Wl,-dead_strip"> ``` Common IDs: - GNU - AppleClang - Clang - MSVC Full list: - <https://cmake.org/cmake/help/v3.20/variable/CMAKE_LANG_COMPILER_ID.html> ## GCC With 32-bit Target On 64-bit Host Possibly in the toolchain file: ```cmake set(CMAKE_C_FLAGS_INIT -m32) set(CMAKE_CXX_FLAGS_INIT -m32) set(CMAKE_EXE_LINKER_FLAGS_INIT -m32) ``` ## function() vs macro() - <https://levelup.gitconnected.com/cmake-variable-scope-f062833581b7> `function()` creates a new child scope, `macro()` uses the same scope. To modify parent variables use: ```cmake set(name value PARENT_SCOPE) ``` ## add_subdirectory() vs include() - <https://levelup.gitconnected.com/cmake-variable-scope-f062833581b7> `add_subdirectory()` creates a new child scope, `include()` uses the same scope. To modify parent variables use: ```cmake set(name value PARENT_SCOPE) ``` ## Recommended Practices When using single configuration generators like Makefiles or Ninja, consider using multiple build directories, one for each build type of interest. Projects should generally avoid using the CMAKE_CROSSCOMPILING variable for any of its logic.