Useful cmake macros that help with: compiler/linker flags, collecting sources, PCHs, Unity builds and other stuff.

Overview

ucm - useful cmake macros

ucm is a collection of cmake macros that help with:

  • managing compiler/linker flags
  • collecting source files with grouping in IDEs that mimics the filesystem structure
  • easy removing source files from already collected ones
  • adding a precompiled header for targets
  • unity builds of targets
  • others... contribution is welcome!

Tested with MSVC/GCC/Clang.

cotire is an optional submodule for the ucm_add_target() macro either do git submodule update --init after cloning or include cotire in your cmake files before ucm.

Language License Linux/OSX Status Windows Status

Documentation

Macros:

Macro notation: myMacro(NAME <name> [FLAG]) - NAME and a name after it are required and FLAG is optional (because in brackets).

macro ucm_print_flags()

Prints all relevant flags - for example with -DCMAKE_BUILD_TYPE=Debug given to cmake for makefiles:

CMAKE_C_FLAGS_DEBUG: -g
CMAKE_CXX_FLAGS_DEBUG: -g
CMAKE_C_FLAGS:  --save-temps -std=c++98 -pedantic -m64 -O2 -fvisibility=hidden
CMAKE_CXX_FLAGS:  --save-temps -std=c++98 -pedantic -m64 -O2 -fvisibility=hidden

or for a multi config generator like Visual Studio:

CMAKE_C_FLAGS_DEBUG: /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
CMAKE_CXX_FLAGS_DEBUG: /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
CMAKE_C_FLAGS_RELEASE: /MD /O2 /Ob2 /D NDEBUG
CMAKE_CXX_FLAGS_RELEASE: /MD /O2 /Ob2 /D NDEBUG
CMAKE_C_FLAGS:  /DWIN32 /D_WINDOWS /W3 /W4
CMAKE_CXX_FLAGS:  /DWIN32 /D_WINDOWS /W3 /GR /EHsc /W4
macro ucm_add_flags([C] [CXX] [CONFIG <config>] flag1 flag2 flag3...)

Append the flags to a different set depending on it's options - examples:

ucm_add_flags(-O3 -Wextra) # will add to CMAKE_C_FLAGS and CMAKE_CXX_FLAGS
ucm_add_flags(C -O3) # will add to CMAKE_C_FLAGS
ucm_add_flags(CXX -O3) # will add to CMAKE_CXX_FLAGS
ucm_add_flags(-O3 -Wall CONFIG Debug) # will add to CMAKE_C_FLAGS_DEBUG and CMAKE_CXX_FLAGS_DEBUG
ucm_add_flags(C -Wall CONFIG Debug Release) # will add to CMAKE_C_FLAGS_DEBUG and CMAKE_C_FLAGS_RELEASE
macro ucm_set_flags([C] [CXX] [CONFIG <config>] flag1 flag2 flag3...)

Removes the old and sets the new flags to a different set depending on it's options - examples:

ucm_set_flags(CXX) # will clear CMAKE_CXX_FLAGS
ucm_set_flags() # will clear both CMAKE_C_FLAGS and CMAKE_CXX_FLAGS
ucm_set_flags(CXX -O3) # will set CMAKE_CXX_FLAGS
ucm_set_flags(-O3 -Wall CONFIG Debug) # will set CMAKE_C_FLAGS_DEBUG and CMAKE_CXX_FLAGS_DEBUG
macro ucm_add_linker_flags([EXE] [MODULE] [SHARED] [STATIC] [CONFIG <config>] flag1 flag2 flag3...)

Append the flags to a different set depending on it's options - examples:

ucm_add_linker_flags(/NXCOMPAT) # will add to CMAKE_<TYPE>_LINKER_FLAGS (TYPE is all 4 - exe/module/shared/static)
ucm_add_linker_flags(EXE /DYNAMICBASE CONFIG Release) # will add to CMAKE_EXE_LINKER_FLAGS_RELEASE only
ucm_add_flags(EXE /DYNAMICBASE CONFIG Debug Release) # will add to CMAKE_EXE_LINKER_FLAGS_DEBUG and CMAKE_EXE_LINKER_FLAGS_RELEASE
macro ucm_set_linker_flags([EXE] [MODULE] [SHARED] [STATIC] [CONFIG <config>] flag1 flag2 flag3...)

Removes the old and sets the new flags to a different set depending on it's options - examples:

ucm_set_linker_flags(/NXCOMPAT) # will clear all CMAKE_<TYPE>_LINKER_FLAGS
ucm_set_linker_flags(EXE /DYNAMICBASE CONFIG Release) # will set CMAKE_EXE_LINKER_FLAGS_RELEASE only
macro ucm_set_runtime([STATIC] [DYNAMIC])

Sets the runtime to static/dynamic - for example with Visual Studio as a generator:

ucm_print_flags()
ucm_set_runtime(STATIC)
ucm_print_flags()

will result in:

CMAKE_C_FLAGS_DEBUG: /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
CMAKE_CXX_FLAGS_DEBUG: /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
CMAKE_C_FLAGS_RELEASE: /MD /O2 /Ob2 /D NDEBUG
CMAKE_CXX_FLAGS_RELEASE: /MD /O2 /Ob2 /D NDEBUG
CMAKE_C_FLAGS:  /DWIN32 /D_WINDOWS /W3 /W4
CMAKE_CXX_FLAGS:  /DWIN32 /D_WINDOWS /W3 /GR /EHsc /W4

CMAKE_C_FLAGS_DEBUG: /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1
CMAKE_CXX_FLAGS_DEBUG: /D_DEBUG /MTd /Zi /Ob0 /Od /RTC1
CMAKE_C_FLAGS_RELEASE: /MT /O2 /Ob2 /D NDEBUG
CMAKE_CXX_FLAGS_RELEASE: /MT /O2 /Ob2 /D NDEBUG
CMAKE_C_FLAGS:  /DWIN32 /D_WINDOWS /W3 /W4
CMAKE_CXX_FLAGS:  /DWIN32 /D_WINDOWS /W3 /GR /EHsc /W4
macro ucm_set_xcode_attrib(name value [CLEAR] [CONFIG <config>])

Sets an Xcode attribute and optionally per-configuration:

ucm_set_xcode_attrib(DEBUG_INFORMATION_FORMAT "dwarf-with-dsym")
ucm_set_xcode_attrib(DEAD_CODE_STRIPPING "YES" CONFIG Debug Release)

will result in:

CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym"
CMAKE_XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING[variant=Debug]: "YES"
CMAKE_XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING[variant=Release]: "YES"
macro ucm_add_files(src1 src2 scr3... TO <sources> [FILTER_POP <num>])

Adds the sources to the sources variable and sets up filters for the solution explorer of Visual Studio (probably for XCode/CodeBlocks too).

The filters will mimic the filesystem - if we have given dir1/test/a.cpp we would have by default dir1/test as nested filters in the solution explorer. This can be controlled with FILTER_POP - 1 would result in only test as a filter and 2 would result in no filter for a.cpp - see ucm_add_dirs for a visual example.

ucm_add_files("dir/some1.cpp" "dir/some1.h" TO sources)
macro ucm_add_dirs(dir1 dir2 dir3... TO <sources> [RECURSIVE] [FILTER_POP <num>] [ADDITIONAL_EXT ext1 ext2 ...])

Adds all sources (sources and headers with all valid c/c++ extensions) from the directories given.

Can be recursive with the RECURSIVE flag.

Like ucm_add_files() filters for the solution explorer of IDEs can be controlled with FILTER_POP - example:

CMake code result
ucm_add_dirs(util TO sources) 0
ucm_add_dirs(util TO sources FILTER_POP 1) 1

Additional extensions for collection can be added with the ADDITIONAL_EXT list.

macro ucm_count_sources(src1 src2 src3... RESULT <result>)

Given a list of sources - returns the number of source files (no headers - only valid source extensions) in the result.

set(sources "a.cpp;b.cpp;h.hpp")
ucm_count_sources(${sources} c.cpp d.cpp RESULT res) # would return 4 in res
macro ucm_include_file_in_sources(src1 src2 src3... HEADER <header>)

Includes the header in the source file with a compile flag (without modifying the file) either with -include "hdr.h" or with /FI"hdr.h" depending on the compiler.

ucm_include_file_in_sources(c.cc a.cc b.cc HEADER "common.h")
macro ucm_dir_list(<thedir> <result>)

Returns a list of subdirectories for a given directory.

ucm_dir_list("the/dir" result)
macro ucm_remove_files(src1 src2 src3... FROM <sources>)

Removes the given source files from the sources list - example:

ucm_add_dirs(utils REC TO sources)
ucm_remove_files(utils/deprecated.h FROM sources)
macro ucm_remove_directories(dir1 dir2 dir3... FROM <sources> [MATCHES pttrn1 pttrn2])

Removes all source files from the given directories from the sources list (recursively) - example:

ucm_add_dirs(utils REC TO sources)
# and then remove only the ones we don't want
ucm_remove_directories(utils/deprecated utils/experimental FROM sources)

Patterns can also be given like this:

ucm_remove_directories(utils FROM sources MATCHES win32)
macro ucm_add_target(NAME <name> TYPE <EXECUTABLE|STATIC|SHARED|MODULE> SOURCES src1 src2 src3... [PCH_FILE <pch>] [UNITY [CPP_PER_UNITY <num>] [UNITY_EXCLUDED excl_src1 excl_src2 ...]])

A wrapper of add_library() and add_executable() calls. Uses cotire for platform/compiler independent usage of precompiled headers and/or making a unity build of the target.

For information about unity builds in general go to the bottom.

ucm_add_target(NAME example TYPE EXECUTABLE SOURCES "${sources}" PCH_FILE precompiled.h)

The example above shows how to add a target with a precompiled header.

ucm_add_target(NAME example TYPE EXECUTABLE SOURCES "${sources}" UNITY CPP_PER_UNITY 20 UNITY_EXCLUDED "separate/some2.cpp")

When the UCM_UNITY_BUILD ucm option is set to ON (OFF by default) a target registered like in the example above will actually result in 2 targets added - the unity target with example as a name (included in the build by default) and the original target with example_ORIGINAL as a name (excluded from the build by default). This allows the user to browse and modify the sources in the original target properly within the IDE. Also separate/some2.cpp will be built normally and will not be included in the unity sources.

When new sources are added to the original target the unity target will be updated accordingly by cotire.

The order in which sources are given to SOURCES is the order in which they will appear in the unity files so you can combat compilation issues by changing the order of the source files.

Targets can be excluded from unity builds by adding them in the UCM_UNITY_BUILD_EXCLUDE_TARGETS list when invoking cmake (handy if a target becomes problematic in a unity build or if you want to iterate fast on a particular target and want to compile it's sources separately).

Mixed language targets (C/C++) are handled properly - separate unity files are generated for the different languages.

The macro will self-diagnose the target and if it has more than 1 source file and has not been registered with the UNITY flag a developer warning will be printed that the target may benefit from a unity build.

CPP_PER_UNITY - to explicitly say how many source files should go into a unity source (default is 100). Another option is to pass not a number but -jX after CPP_PER_UNITY and that would mean dividing the sources into X unity sources.

UNITY_EXCLUDED - list of files from the target that should be excluded from unify-ing (will be used normally by themselves - can be used to fix compilation errors).

Unity examples - given 100 .cpp files in the target:

  • CPP_PER_UNITY 5 would mean 20 .cxx unity files including 5 of the original .cpp files each
  • CPP_PER_UNITY 10 would mean 10 .cxx unity files including 10 of the original .cpp files each
  • CPP_PER_UNITY -j8 would mean 8 .cxx unity files dividing the original 100 among them

How a unity target looks in the IDE:

1

Unity builds

For all the pros and cons checkout my blog post.

Comments
  • As of 37303d8, ucm_add_linker_flags is broken

    As of 37303d8, ucm_add_linker_flags is broken

    Example of something we have for Visual Studio 2015: ucm_add_linker_flags(EXE /DEBUG:Fastlink CONFIG Release)

    This worked fine before. It adds that option to the "Configuration Properties->Linker->Generate Debug Info" project property. As of 37303d8, it doesn't do anything.

    opened by ruifig 3
  • Usage of precompiled headers

    Usage of precompiled headers

    I did not really get how to use the precompiled headers with ucm.

    There is in the ucm_add_target() the PCH parameter. This probably should activate the usage of the generated pch. But when I compile this target with -H as compile flag there is no precompiled header used. Only if I specified a header file with the PCH_FILE parameter. Is this the expected behavior?

    Though, this is not a big problem for me, because I want to specify the precompiled header myself. I want to use the same pch for every target and it should only be compiled once. Is this possible with ucm?

    opened by mirkow 3
  • Set STATUS mode for CMake message() function calls

    Set STATUS mode for CMake message() function calls

    Not having a mode causes the message to print to stderr instead of stdout.

    There are some setups where anything printed to stderr is considered an error for the purposes of determining if a subprocess worked or not. I recently encountered this problem where messages getting printed to stderr by CMake were causing commands to terminate (on CI builds) -- it seemed to be most problematic when using powershell to run a setuptools build (that compiles a native module using CMake).

    opened by nightlark 1
  • Add ability to set xcode attributes

    Add ability to set xcode attributes

    I have made a modification to my fork that might be useful for others - the ability to set xcode attributes on a per-configuration basis.

    ucm_set_xcode_attrib(DEBUG_INFORMATION_FORMAT "dwarf-with-dsym")
    ucm_set_xcode_attrib(DEAD_CODE_STRIPPING "YES" CONFIG Debug Release)
    

    will result in:

    CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT: "dwarf-with-dsym"
    CMAKE_XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING[variant=Debug]: "YES"
    CMAKE_XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING[variant=Release]: "YES"
    
    opened by nmoinvaz 1
  • add check for unrecognized arguments to ucm_set_runtime

    add check for unrecognized arguments to ucm_set_runtime

    Adds a simple check for unrecognized arguments to ucm_set_runtime. It may not make a difference in practice, but I prefer to be rigorous and alert the user if there are redundant arguments.

    Possible problems:

    • May break backwards compatibility. Maybe use a warning instead of error?
    opened by tschuchortdev 1
  • add flags to multiple configs at once

    add flags to multiple configs at once

    This PR makes it possible to add compiler and linker flags to multiple configs at once. A use case for this would be for example if you want to add flags both to Release and RelWithDebInfo:

    ucm_add_flags(-Werror CONFIG Release RelWithDebInfo)

    opened by tschuchortdev 1
Owner
Viktor Kirilov
Working on Nimbus - an Ethereum 1.0 & 2.0 Client for Resource-Restricted Devices. I created doctest.
Viktor Kirilov
Violent Fungus is a command and control (C2) software suite, providing red teams post-exploitation persistence and other juicy stuff.

Violent Fungus is a command and control (C2) software suite, providing red teams post-exploitation persistence and other juicy stuff.

Chris Humphries 34 Sep 7, 2022
a simple project made with a esp32 and some other stuff

pumkin candy dispenser its a really simple candy dispenser that it works with a esp32 ai thinker. I made it for a school project and idk it looks cool

ranon rat 7 Jul 15, 2022
a simple project made with a esp32 and some other stuff

pumpkin candy dispenser its a really simple candy dispenser that it works with a esp32 ai thinker. I made it for a school project and idk it looks coo

ranon rat 7 Jul 15, 2022
GLSL optimizer based on Mesa's GLSL compiler. Used to be used in Unity for mobile shader optimization.

GLSL optimizer ⚠️ As of mid-2016, the project is unlikely to have any significant developments. At Unity we are moving to a different shader compilati

Aras Pranckevičius 1.6k Jan 3, 2023
A set of one-line C++ macros to simplify the creation of reccurent things in Qt projects

QDefs A set of one-line C++ macros to simplify the creation of reccurent things in Qt projects (like Qt Meta Properties) so that doing them in C++ is

null 3 Nov 2, 2022
Contribute your handwritten PDF notes and help other students ✌ #DecodersCommunity 🖤

Contribute your handwritten PDF notes and help other students ✌ #DecodersCommunity ??

Decoders Community 37 Nov 22, 2022
A C library for runtime-flippable feature flags on Linux/x86-64, with negligible overhead in the common case

Biased runtime-flippable flags, with cross-modifying code The dynamic_flag library is a two-file "C" library that offers efficient biased conditionals

Backtrace Labs 61 Dec 14, 2022
PoC tool to coerce Windows hosts to authenticate to other machines via MS-EFSRPC EfsRpcOpenFileRaw or other functions.

PetitPotam PoC tool to coerce Windows hosts to authenticate to other machines via MS-EFSRPC EfsRpcOpenFileRaw or other functions :) The tools use the

Topotam 1.4k Jan 4, 2023
This is a imgui login that runs with keyauth with only uses the key and has tabs for you to paste your stuff in c++

KeyAuth-Imgui-key-Login This is a imgui login that runs with keyauth with only uses the key and has tabs for you to paste your stuff in c++ KeyAuth CP

Lucent 12 Dec 16, 2022
Builds and runs an exported image classification impulse on ESP32 Cam

ESP32 Cam and Edge Impulse How to run custom inference on a ESP32 cam using Edge Impulse. Material This code has been tested the AI Thinker ESP32 Cam

Edge Impulse 65 Dec 31, 2022
I add my Pi Pico (RP2040) stuff here.

Pico Stuff I add my Pi Pico (RP2040) stuff here. There are complete apps and libraries for sensors or complicated tasks. Libraries BMP180: Header-only

Luigi Cruz 108 Jan 8, 2023
Collection of cross-platform single-header C libraries for doing a lot of stuff! (Still WIP)

ice_libs Collection of cross-platform single-header C libraries for doing a lot of stuff! (Still WIP) Brief ice_libs is collection of Single-Header C

Rabia Alhaffar 118 Dec 6, 2022
Stuff I've made/found for reversing/modding/extracting NieR:Replicant v1.224...

NieR:Replicant ver.1.22474487139 Tools Archive (.arc) Files Hex Signature: 28 B5 2F FD Can contain one or multiple compressed files. Files are compres

Woeful_Wolf 8 Jul 30, 2022
A DLL that fixes some stuff on Fortnite OT 6.5. Originally based on Alphaium by Cyuubi

How to use Compile as x86 because alpha is 32 bit Setup the responses Inject while in the login screen Wait for the console to tell you to login Respo

null 14 Jul 23, 2022
Custom kernel for sweet based on Delta, builds hosted on @sweet_epsilon on Telegram (GH releases are outdated)

Linux kernel ============ This file was moved to Documentation/admin-guide/README.rst Please notice that there are several guides for kernel develop

Udit Karode 14 Mar 29, 2022
My builds of suckless software

I recently switched to dwm from i3wm, it took me a while to get used to the dwm stuff and also the suckless way. After dwm, came st and then slstatus

Kushagra Jain 2 Nov 19, 2021
Builds atlas texture from a bunch of input images.

Atlasc @septag atlasc is a command-line program that builds atlas texture from a bunch of input images. Main Features Cross-platform. Runs on linux/ma

Sepehr Taghdisian 74 Aug 30, 2022
This FreeRTOS example builds a simple Timer application for Linux using the ESP-IDF

Supported Targets Linux This FreeRTOS example builds a simple Timer application for Linux using the ESP-IDF. Build Source the IDF environment as usual

null 13 Apr 4, 2022
Automated builds/mirrors of various PS3SDKs for Linux systems.

Working PS3SDK Binaries NOTICE: This repo is now deprecated. SDK builds have moved here, and SDK mirrors have moved here. Prepares and releases workin

null 3 Jan 29, 2022