cmake - overrid set(CMAKE_CXX_FLAGS ...) from command line - cmake

My client's cmake configuration includes the following boilerplate:
include(CheckCXXCompilerFlag)
# add compiler flag, if not already present
macro(add_compiler_flag flag supportsFlag)
check_cxx_compiler_flag(${flag} ${supportsFlag})
if(${supportsFlag} AND NOT "${CMAKE_CXX_FLAGS}" MATCHES "${flag}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
endif()
endmacro()
add_compiler_flag("-Werror=suggest-override" supportsSuggestOverride)
This causes my build to fail because of missing override declarations in the header files for boost 1.81.
How can I override that flag from the command line? I tried this...
cmake -DCMAKE_CXX_FLAGS="-Wno-error=suggest-override" ..
...it did not work.

Related

How to create CMakeLists for this make file [duplicate]

Work on Ubuntu 16
I used g++ main.cpp -lpq command for compiler my small project. Now I use Clion and wanna do same what I do with g++. But I can't add compiler flags in cmake file and get compile error.
cmake_minimum_required(VERSION 3.5.1)
project(day_g)
set(CMAKE_CXX_FLAGS "-lpq")
add_definitions(-lpq)
message("CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(day_g ${SOURCE_FILES})
Also I run only cmake file and get CMAKE_CXX_FLAGS with -lpq flag.
CMAKE_CXX_FLAGS is -lpq
-- Configuring done
-- Generating done
How properly add compiler flags to cmake file?
Flag -l is for linker, not for compiler. This flag is used for link with libraries. CMake has special command target_link_libraries for that purpose:
target_link_libraries(day_g pq)
-lq is not a compiler flag (CFLAGS) but a linker flag.
To pass a library in a CMake project you should use:
target_link_libraries(target_name libraries...)
Note that if you specify 'q' as library the project will link with libq.a or, if you are on windows q.dll.
... in your CMakeLists.txt the correct line to add is:
target_link_libraries(day_g pq)
Note also that when you add a CFLAG you should also "remember" the previous ones that may be added by libraries or by your platform, ie:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
To check the exact flags cmake is passing to compiler or linker you can always run, from the build directory, the following command:
make VERBOSE=1

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

CMake not respecting command line options

Ubuntu 14_04, gcc 4.8.4, cmake 2.8.12.2
I wish to add additional options to UnitTest++. I added code coverage via UTPP_CODE_COVERAGE but leave it off for regular builds. This seemed to fail - nothing is in the Makefile that looks to be specified via the set(CMAKE_CXX_FLAGS option.
So I looked at whether the UTPP_AMPLIFY_WARNINGS command works
Whether I compile with it on or off, no difference is made to the Makefile.
At the terminal I compile with
$ cmake -G "Unix Makefiles" -DUTPP_AMPLIFY_WARNINGS=ON ../
But when I analyse the generated Makefile -Wall is nowhere to be found in the output. It's not even in the CMakeCache.txt
What am I doing wrong?
I can confirm what you have observed. There seems that the required warning level is already default in the CMakeLists.txt file and also the command set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror") setting the -Wall flag is reached and executed (have tested this using message(). If there is no other answer here, at least you know you are not alone wondering how it comes.
cmake_minimum_required(VERSION 2.8.1)
project(UnitTest++)
option(UTPP_USE_PLUS_SIGN
"Set this to OFF if you wish to use '-cpp' instead of '++' in lib/include paths"
ON)
option(UTPP_INCLUDE_TESTS_IN_BUILD
"Set this to OFF if you do not wish to automatically build or run unit tests as part of the default cmake --build"
ON)
option(UTPP_AMPLIFY_WARNINGS
"Set this to OFF if you wish to use CMake default warning levels; should generally only use to work around support issues for your specific compiler"
ON)
...
# up warning level for project
if (${UTPP_AMPLIFY_WARNINGS})
# instead of getting compiler specific, we're going to try making an assumption that an existing /W# means
# we are dealing with an MSVC or MSVC-like compiler (e.g. Intel on Windows)
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
# message(STATUS "CMAKE_CXX_FLAGS MATCHES")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
else()
# message(STATUS "set(CMAKE_CXX_FLAGS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
endif()
endif()

Disable -Werror for one of CMakeLists.txt

I have the following CMake file:
project(MyLib)
cmake_minimum_required(VERSION 2.8)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "release")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror")
set(ROOT_DIR ${CMAKE_SOURCE_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROOT_DIR}/bin/${CMAKE_BUILD_TYPE})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DIR}/bin/${CMAKE_BUILD_TYPE})
set(MAIN_LIBRARY_NAME "mylib")
add_subdirectory(src)
add_subdirectory(test_app)
add_subdirectory(test_app1) <--- I want to disable -Werror flag for CMakeLists.txt in this folder.
add_subdirectory(test_app2)
How to disable -Werror flag for one of subdirectories? In the each of sub directories I have CMakeLists.txt too.
Turning my comment into an answer
All variables and directory properties are copied to the subdirectory's context at the moment you call add_subdirectory(). Either modify CMAKE_CXX_FLAGS before this call with something like
string(REPLACE " -Werror" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
add_subdirectory(test_app1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
Or use the "old way" were compiler flags could be given with add_definitions() and removed with remove_definitions()
add_definitions(-std=c++11 -Wall -Werror)
...
remove_definitions(-Werror)
add_subdirectory(test_app1)
add_definitions(-Werror)
But you can - in contradiction to my first comment - change flags added add_compile_options() only on target level COMPILE_OPTIONS property and not for complete directories. When the target is created the property is copied as-is from the directory to the target and changing the directory property later won't automatically update the target's property.
If you have a newer CMake version that supports SOURCE_DIR target property you can alternatively go by some crazy generator expression:
add_compile_options(
-std=c++11
-Wall
$<$<NOT:$<STREQUAL:$<TARGET_PROPERTY:SOURCE_DIR>,${CMAKE_SOURCE_DIR}/test_app1>>:-Werror>
)
Reference
Is Cmake set variable recursive?
If you are using CMake v3.24's new CMAKE_COMPILE_WARNING_AS_ERROR variable, which initializes the corresponding target property, you can simply set the variable to FALSE in the CMakeLists.txt file of any subdirectories where you won't want warnings to be errors.
There are two nice things about using this variable:
Cross-platform with less boilerplate: No more explicitly written generator expressions to use the right flag for each compiler.
Allows user-override: Not all users will want to build with warnings as errors. This new feature comes with a --compile-no-warning-as-error command-line flag that users can use to disable any effects of this variable/target-property when set by a dev in a CMakeLists.txt file.
we have a project setup which configured Werror and Wall at the top level as compiler flags. What I ended up doing for a temporary test program which I wanted to skip Werror was:
add_executable(test_program ...)
target_compile_options(test_program PRIVATE -Wno-error)
that ended up generating a compile line like:
g++ ... -Wall -Werror -Wno-error test.cpp -o test
where the -Wno-error cancels out the -Werror, without affecting the CXXFLAGS for the rest of the project.

CMake: How to add dependency on linker script for executable

I have a CMake script where the final executable is linked with my own linker script:
cmake_minimum_required(VERSION 3.1)
project(test_app)
set(LINKER_SCRIPT "linker.ld")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T ${LINKER_SCRIPT}")
add_executable(${PROJECT_NAME}.elf
main.cpp
startup.cpp
)
How do I make an executable dependent also on the linker script file (trigger linking if linker.ld was changed)?
You can add a LINK_DEPENDS property to your executable target, using set_target_properties. Add the following line after your add_executable command:
set_target_properties(${TARGET_NAME} PROPERTIES LINK_DEPENDS ${LINKER_SCRIPT})
The first argument to set_target_properties is the target name, i.e. the first argument you passed to add_executable.
I found this mail which described three possible ways for forcing an executable to be dependent on a linker script. Its author prefers this way:
CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LINKERSCRIPT C)
FILE(WRITE main.c "void main(){}")
# dummy.c must exist:
ADD_EXECUTABLE(EXE main.c dummy.c)
# linkerscript must exist:
SET_SOURCE_FILES_PROPERTIES(
dummy.c PROPERTIES OBJECT_DEPENDS ${CMAKE_SOURCE_DIR}/linkerscript
)
Here dummy.c is an empty file, which is listed for the add_executable() command only for make resulted executable dependent on the linker script via the OBJECT_DEPENDS property.