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

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.

Related

CMake get all flags, includes and defines programatically

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

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
)

CMake + CUDA + separable compilation -> "nvcc doesn't know what to do with ' ' "

I use CMake for a project of mine involving CUDA. Recently I have had to turn on "separable compilation" of the some of my CUDA code:
set(CUDA_SEPARABLE_COMPILATION ON)
but then, building started to fail. As an example, the following would happen:
/usr/local/cuda/bin/nvcc -gencode arch=compute_30,code=compute_30 --std=c++11 \
-Xcompiler -Wall -O3 -DNDEBUG "" "" "" "" -m64 -ccbin /usr/bin/cc \
-dlink /some/where/generated_foo.cu.o -o /some/where/foo_intermediate_link.o
nvcc fatal : Don't know what to do with ''
(lines broken and names shortened for readability)
So, the problem is that something triggers CMake to add some empty (quoted) strings to the command-line, which nvcc doesn't like. Other than that the command seems fine.
Now, -O3 -DNDEBUG are my nvcc compilation flags for release builds. But I've certainly not added any empty-string flags anywhere. I tried looking into how FindCUDA constructs the nvcc invocation, but couldn't quite figure out where these empty strings are coming.
Without going into the specifics of my CMakeLists.txt, could this possibly be a well-known issue with CMake's FindaCUDA module which has a general workaround?
Note: I use GNU/Linux Mint 18.3, CMake 3.5, and CUDA 9.1.
It turns out this is a known CMake issue.
The workaround is to only set build-config-specific compilation flags for the active build config, e.g. instead of having:
set(CUDA_NVCC_FLAGS_RELEASE ${CUDA_NVCC_FLAGS_RELEASE} -O3)
set(CUDA_NVCC_FLAGS_DEBUG ${CUDA_NVCC_FLAGS_DEBUG} -g --generate-line-info)
in your CMakeLists.txt, use:
if (CMAKE_BUILD_TYPE_UPPER STREQUAL "RELEASE")
set(CUDA_NVCC_FLAGS_RELEASE ${CUDA_NVCC_FLAGS_RELEASE} -O3)
elseif (CMAKE_BUILD_TYPE_UPPER STREQUAL "DEBUG")
set(CUDA_NVCC_FLAGS_DEBUG ${CUDA_NVCC_FLAGS_DEBUG} -g --generate-line-info)
endif (CMAKE_BUILD_TYPE_UPPER STREQUAL "RELEASE")
instead (or more cases if you have multiple build types).
Another possible alternative is to not use FindCUDA at all, as CMake has added support for CUDA as a "first-class" language beginning with some 3.X release (not sure what X is).

How to add a custom build type to cmake?

I want to add my build type to cmake to call cmake like this:
cmake -DCMAKE_BUILD_TYPE=mytype
I've written strings to my CMakeLists.txt:
set(CMAKE_CXX_FLAGS_DEBUG "-fPIC -o0 -g")
set(CMAKE_CXX_FLAGS_MYTYPE "-fPIC -o0 -g -m32)
set(CMAKE_CXX_FLAGS_RELEASE "-fPIC -o3)
But cmake uses compiler flags which were wrote in CMAKE_CXX_FLAGS_DEBUG.
What I should do to add my build type correctly?
I've fond soulution. set function must be before project() directive.

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.