CMake get all flags, includes and defines programatically - cmake

I'm using CMake 3.12 with linux and I try to extract all flags, includes and defines programatically from a target.
I found some help online, but it was always limited to the default settings induced by CMake.
For example with the variables :
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
...
Here I'm missing external flags.
I' stumbled upon the file "flags.make" located in the build folder of the project:
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.12
# compile C with /usr/bin/gcc-4.8
C_FLAGS = -O3 -DNDEBUG -fPIC
C_DEFINES = -DLINUX -DLINUX64 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
C_INCLUDES =
Which is exactly what I need. Does anybody know how to access these variables within CMake?
Thank you!
Best regards
Fabian

Related

CMake invocation of GLSLC with respect to includes/dependencies

I'm using glslc to compile GLSL shaders with #includes (not part of the core spec IIRC but supported in shaderc, which is the engine behind glslc, distributed with the LunarG Vulkan SDK) into SPIR-V for Vulkan and GL 4.5. glslc emits gcc-style depsfiles ([my_shader].[ext].d) files containing dependency info.
My project is built with cmake/ninja/MSVC 2017.
Today, I use a cmake custom_command to invoke glslc when a shader has changed on disk, as a post-build step to my primary target. However, this doesn't catch the changes in included files (isn't at all aware of the .d files or their contents), so rebuilding shaders when an included glsl file is changed can trip up myself and other people on my team.
It looks like ninja can invoke arbitrary compilers, and since ninja knows how to handle the depsfiles, I should be able to coerce ninja into running glslc -- unsure about other build systems since right now we're standardized on ninja.
So how can I tell cmake to configure ninja to use glslc for a specific target? Or is there a paradigmatic way to get this done? It looks like a cmake pull request to add support for glslc as a compiler didn't make it in to cmake circa 2016, so whatever I do is going to be a workaround.
CMake understands depfiles when used in conjunction with ninja.
DEPFILE
Specify a .d depfile for the Ninja generator. A .d file holds dependencies usually emitted by the custom command itself. Using DEPFILE with other generators than Ninja is an error.
add_custom_command(
OUTPUT ${source}.h
DEPENDS ${source}
COMMAND
glslc
-MD -MF ${source}.d
-o ${source}.h -mfmt=num
--target-env=opengl
${CMAKE_CURRENT_SOURCE_DIR}/${source}
DEPFILE ${source}.d
)
-M Generate make dependencies. Implies -E and -w.
-MM An alias for -M.
-MD Generate make dependencies and compile.
-MF <file> Write dependency output to the given file.
-MT <target> Specify the target of the rule emitted by dependency
generation.
EDIT: Getting fancier
find_package(Vulkan COMPONENTS glslc)
find_program(glslc_executable NAMES glslc HINTS Vulkan::glslc)
function(compile_shader target)
cmake_parse_arguments(PARSE_ARGV 1 arg "" "ENV;FORMAT" "SOURCES")
foreach(source ${arg_SOURCES})
add_custom_command(
OUTPUT ${source}.${arg_FORMAT}
DEPENDS ${source}
DEPFILE ${source}.d
COMMAND
${glslc_executable}
$<$<BOOL:${arg_ENV}>:--target-env=${arg_ENV}>
$<$<BOOL:${arg_FORMAT}>:-mfmt=${arg_FORMAT}>
-MD -MF ${source}.d
-o ${source}.${arg_FORMAT}
${CMAKE_CURRENT_SOURCE_DIR}/${source}
)
target_sources(${target} PRIVATE ${source}.${arg_FORMAT})
endforeach()
endfunction()
add_executable(dummy dummy.c)
compile_shader(dummy
ENV opengl
FORMAT num
SOURCES
dummy.vert
dummy.frag
)

Compiler flags settings in CMAKE scripts

I am facing below issue while running my build:
C:/Test.cpp: In member function '........':
C:/Test.cpp:291:50: error: 'round_one' may be used uninitialized in this function [-Werror=maybe-uninitialized]
I tried to grep for string maybe-uninitialized in my whole source code but I could not find one. I was expecting some declaration like below:
set_source_files_properties(ROOT_DIR/Test.cpp PROPERTIES COMPILE_FLAGS "-Wno-maybe-uninitialized -Wno-misleading-indentation" )
or
SET(GCC_COVERAGE_COMPILE_FLAGS "-Wno-maybe-uninitialized")
add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
But I could not find any - please let me know how Compiler flags are set in CMAKE utility?
The warning -Wmaybe-uninitialized is one of those that are enabled
by -Wall.
-Wall is always specified by proficient programmers. Warnings will be converted
to errors by -Werror, so the flags -Wall -Werror will produce -Werror=maybe-uninitialized,
as per your diagnostic, if a potentially uninitialized variable is detected.
You will very likely find -Wall ... -Werror in the specified compiler flags in the relevant CMakeLists.txt
One way is setting the add compiler flag for the project:
cmake_minimum_required(VERSION 2.8)
# Project
project(008-compile-flags-01)
# Add compile flag
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHELLO_WORLD" CACHE STRING "Hello World Define." FORCE)
# Executable source files
set(executable_SOURCES src/main.cpp)
# Executable
add_executable(executable ${executable_SOURCES})
Other way is setting compiler flag for the target:
cmake_minimum_required(VERSION 3.2)
# Project
project(008-compile-flags-03)
# Executable source files
set(executable_SOURCES src/main.cpp)
# Executable
add_executable(executable ${executable_SOURCES})
# Add compile flag
target_compile_options(executable PRIVATE -DHELLO_WORLD)
Other way is using target_compile_features. I haven't used this before. Please see:
https://cmake.org/cmake/help/latest/command/target_compile_features.html
https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html

How to disable cmake setting CXX_FLAGS = -std=c++1y -g -O3 -std=gnu++11

cmake generates the flags.make file with
CXX_FLAGS = -std=c++1y -g -O3 -std=gnu++11
The first -std is set by me and the second is generated by cmake. I can't understand where the second one comes from or how to disable it.
Has someone encountered the same issue and know how to resolve this?
Without having your code/project it's difficult to tell. Just a guess: you are including/depending on an external library that does need C++11 (e.g. Boost) and has requested it from CMake.
So to override this with your own need for C++14 you can either set globally CMAKE_CXX_STANDARD with something like:
set(CMAKE_CXX_STANDARD 14)
or with naming specific compiler features needed in your library/executable.

CMake, static library and link time optimization

I'm trying to create static library with link time optimization using cmake and g++.
set(
CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -Wall -Werror -Wextra -pedantic -std=c++11"
)
if (CMAKE_COMPILER_IS_GNUCXX)
set(
CMAKE_STATIC_LINKER_FLAGS_RELEASE
"${CMAKE_STATIC_LINKER_FLAGS_RELEASE} -flto -fwhole-program"
)
endif()
add_library(
mylib STATIC
mylib.cpp
)
But when running typical
cmake -DCMAKE_BUILD_TYPE=Release ..
make
I'm getting following error:
/usr/bin/ar: two different operation options specified
link.txt file contains following commands:
/usr/bin/ar cq libmylib.a -flto -fwhole-program CMakeFiles/mylib.cpp.o
/usr/bin/ranlib libmylib.a
From what I understand from running ar --help the -flto -fwhole-program should be before libmylib.a in the first line. But I have no idea how to force CMake to put it there.
Is my assumption correct? And how can I resolve this?
EDIT: I'd like to add that I'm completely new to using LTO so if it doesn't make sense to use it for static libraries, please do tell me so.
-flto isn't a valid option for ar. You should instead use these flags for CMAKE_EXE_LINKER_FLAGS.

Compiling with cmake and include debug information

cmake version 2.8.5
I am trying to compile my project using cmake. However, when i compile I don't think I am including the debug cflags i.e. -ggdb -D_DEBUG. As when I try and debug there is no debub info.
Is there any problem with the CMakeLists.txt files. I have 3 of them
# Mimimum version of cmake required
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
# Name of project
PROJECT(sdp_creator C)
# Check for correct compiler
# Using C compiler GNUCXX for c++ compiler
IF(CMAKE_COMPILER_IS_GNUCC)
MESSAGE(STATUS "=== GCC C COMPILER DETECTED")
SET(CMAKE_C_FLAGS "-m32 -ggdb -D_DEBUG -Wextra -Wall -Wunreachable-code -O0 -D_LARGEFILE64_SOURCE")
ENDIF(CMAKE_COMPILER_IS_GNUCC)
# Using windows compiler i.e. msvc++
IF(WIN32)
MESSAGE(STATUS "=== MSVC COMPILER DETECTED")
ENDIF(WIN32)
# Location of directory where include files are kept
INCLUDE_DIRECTORIES($ENV{HOME}/projects/sdp_creator/src/sdp)
INCLUDE_DIRECTORIES($ENV{HOME}/projects/sdp_creator/src/apr/inc)
# Location of directory where libraries are kept
LINK_DIRECTORIES($ENV{HOME}/projects/sdp_creator/src/apr/lib)
# Add subdirectories
ADD_SUBDIRECTORY(driver)
ADD_SUBDIRECTORY(sdp)
building shared library:
# Create a shared library called libsdp from sdp.c
# NOTE: static is the default
# NOTE: the lib prefix is automatically added
ADD_LIBRARY(sdp SHARED sdp.c)
Creating executable:
# Add executable called sdp_creator from source file
ADD_EXECUTABLE(sdp_creator main.c)
# Link the sdp library and other libraries with the excutable
#if using windows compiler add additional windows libraries
IF(WIN32)
TARGET_LINK_LIBRARIES(sdp_creator libsdp ws2_32)
MESSAGE(STATUS "=== Linking executable with windows libraries")
ENDIF(WIN32)
# if using gcc compiler
# NOTE: no need to add the -l prefix i.e. -lsdp, no automatically
IF(CMAKE_COMPILER_IS_GNUCC)
TARGET_LINK_LIBRARIES(sdp_creator sdp apr-1)
MESSAGE(STATUS "=== Linking executable with posix libraries")
ENDIF(CMAKE_COMPILER_IS_GNUCC)
Many thanks for any advice,
If you're using the "Unix Makefiles" (or any Makefile-based) generator, set the variable CMAKE_BUILD_TYPE to "Debug"
cmake -DCMAKE_BUILD_TYPE=Debug ../src
That will automatically add the right definitions and flags for your compiler. You should not have to add any flags yourself.
With multi-configuration generators, (like Visual Studio and Xcode), CMAKE_BUILD_TYPE is ignored, because the choice of whether to build a Debug or Release configuration is left up to the developer at build-time, and is not known at CMake configure time.
You can check the exact steps used in make by setting VERBOSE=1. That will tell you if the flags were included or not.
cmake project_dir
make VERBOSE=1
You can also check the CMakeCache.txt to see what value is assigned to CMAKE_C_FLAGS variable.
you can use the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS flags with -g0/1/2 (debug information flag for the compiler. -g2 is the highest information):
cmake ... -DCMAKE_C_FLAGS="-g2" -DCMAKE_CXX_FLAGS="-g2" ...
Another option, if unix Makefiles are used to build the project, is to set CMAKE_BUILD_TYPE in CMakeLists.txt file directly:
set(CMAKE_BUILD_TYPE Debug)
You can find more in
$ man cmakevars
Look for CMAKE_BUILD_TYPE