How to add CFLAGS and CXXFLAGS and LDFLAGS to file.cmake? [duplicate] - gcc

I am using the arm-linux-androideabi-g++ compiler. When I try to compile a simple "Hello, World!" program it compiles fine. When I test it by adding a simple exception handling in that code it works too (after adding -fexceptions .. I guess it is disabled by default).
This is for an Android device, and I only want to use CMake, not ndk-build.
For example - first.cpp
#include <iostream>
using namespace std;
int main()
{
try
{
}
catch (...)
{
}
return 0;
}
./arm-linux-androideadi-g++ -o first-test first.cpp -fexceptions
It works with no problem...
The problem ... I am trying to compile the file with a CMake file.
I want to add the -fexceptions as a flag. I tried with
set (CMAKE_EXE_LINKER_FLAGS -fexceptions ) or set (CMAKE_EXE_LINKER_FLAGS "fexceptions" )
and
set ( CMAKE_C_FLAGS "fexceptions")
It still displays an error.

Note: Given CMake evolution since this was answer was written in 2012, most of the suggestions here are now outdated/deprecated and have better alternatives.
Suppose you want to add those flags (better to declare them in a constant):
SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
SET(GCC_COVERAGE_LINK_FLAGS "-lgcov")
There are several ways to add them:
The easiest one (not clean, but easy and convenient, and works only for compile flags, C & C++ at once):
add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
Appending to corresponding CMake variables:
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
Using target properties, cf. doc CMake compile flag target property and need to know the target name.
get_target_property(TEMP ${THE_TARGET} COMPILE_FLAGS)
if(TEMP STREQUAL "TEMP-NOTFOUND")
SET(TEMP "") # Set to empty string
else()
SET(TEMP "${TEMP} ") # A space to cleanly separate from existing content
endif()
# Append our values
SET(TEMP "${TEMP}${GCC_COVERAGE_COMPILE_FLAGS}" )
set_target_properties(${THE_TARGET} PROPERTIES COMPILE_FLAGS ${TEMP} )
Right now I use method 2.

In newer versions of CMake you can set compiler and linker flags for a single target with target_compile_options and target_link_libraries respectively (yes, the latter sets linker options too):
target_compile_options(first-test PRIVATE -fexceptions)
The advantage of this method is that you can control propagation of options to other targets that depend on this one via PUBLIC and PRIVATE.
As of CMake 3.13 you can also use target_link_options to add linker options which makes the intent more clear.

Try setting the variable CMAKE_CXX_FLAGS instead of CMAKE_C_FLAGS:
set (CMAKE_CXX_FLAGS "-fexceptions")
The variable CMAKE_C_FLAGS only affects the C compiler, but you are compiling C++ code.
Adding the flag to CMAKE_EXE_LINKER_FLAGS is redundant.

The preferred way to specify toolchain-specific options is using CMake's toolchain facility. This ensures that there is a clean division between:
instructions on how to organise source files into targets -- expressed in CMakeLists.txt files, entirely toolchain-agnostic; and
details of how certain toolchains should be configured -- separated into CMake script files, extensible by future users of your project, scalable.
Ideally, there should be no compiler/linker flags in your CMakeLists.txt files -- even within if/endif blocks. And your program should build for the native platform with the default toolchain (e.g. GCC on GNU/Linux or MSVC on Windows) without any additional flags.
Steps to add a toolchain:
Create a file, e.g. arm-linux-androideadi-gcc.cmake with global toolchain settings:
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_CXX_FLAGS_INIT "-fexceptions")
(You can find an example Linux cross-compiling toolchain file here.)
When you want to generate a build system with this toolchain, specify the CMAKE_TOOLCHAIN_FILE parameter on the command line:
mkdir android-arm-build && cd android-arm-build
cmake -DCMAKE_TOOLCHAIN_FILE=$(pwd)/../arm-linux-androideadi-gcc.cmake ..
(Note: you cannot use a relative path.)
Build as normal:
cmake --build .
Toolchain files make cross-compilation easier, but they have other uses:
Hardened diagnostics for your unit tests.
set(CMAKE_CXX_FLAGS_INIT "-Werror -Wall -Wextra -Wpedantic")
Tricky-to-configure development tools.
# toolchain file for use with gcov
set(CMAKE_CXX_FLAGS_INIT "--coverage -fno-exceptions -g")
Enhanced safety checks.
# toolchain file for use with gdb
set(CMAKE_CXX_FLAGS_DEBUG_INIT "-fsanitize=address,undefined -fsanitize-undefined-trap-on-error")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fsanitize=address,undefined -static-libasan")

You can also add linker flags to a specific target using the LINK_FLAGS property:
set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${flag}")
If you want to propagate this change to other targets, you can create a dummy target to link to.

This worked for me when I needed a precompile definition named "NO_DEBUG":
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -DNO_DEBUG")
Then from code
#ifdef NO_DEBUG
.....

With CMake 3.4+, APPEND can be used with the string command to add flags.
string(APPEND CMAKE_EXE_LINKER_FLAGS " -fexceptions")

Related

cmake enable g++ -std=c++11 [duplicate]

I'm trying to run C++11 code in CLion but it doesn't work. It says:
...
/projects/CLion/untitled/main.cpp:7:1: note: C++11 ‘constexpr’ only available with -std=c++11 or -std=gnu++11
...
I tried to set CMAKE_C_FLAGS to -std=c++11 or -std=gnu++11 but I still have the same problem. Regular C++ code compiles fine.
What flag do I have to set in CLion's CMake window to compile my C++11 code?
I tried to set CMAKE_C_FLAGS
According to the documentation the CMAKE_C_FLAGS set C language flags for all build types. For C++ you need use CMAKE_CXX_FLAGS instead:
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
For CMake 3.1 or later, you can set the CMAKE_CXX_STANDARD variable to 11:
Default value for CXX_STANDARD property of targets.
This variable is used to initialize the CXX_STANDARD property on all targets.
CXX_STANDARD documentation:
The C++ standard whose features are requested to build this target.
This property specifies the C++ standard whose features are requested to build this target. For some compilers, this results in adding a flag such as -std=gnu++11 to the compile line.
Supported values are 98, 11 and 14.
If the value requested does not result in a compile flag being added for the compiler in use, a previous standard flag will be added instead. This means that using:
set_property(TARGET tgt PROPERTY CXX_STANDARD 11)
with a compiler which does not support -std=gnu++11 or an equivalent flag will not result in an error or warning, but will instead add the -std=gnu++98 flag if supported. This “decay” behavior may be controlled with the CXX_STANDARD_REQUIRED target property.
See the cmake-compile-features(7) manual for information on compile features.
This property is initialized by the value of the CMAKE_CXX_STANDARD variable if it is set when a target is created.

How to create a makefile for Keystone library using cmake? [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

Enable compiler warnings in Kdevelop

I'm using Kdevelop for a simple C++ project. I know that Kdevelop uses CMake to build the project, but the only thing that I known about CMake is that if I add a new .cpp source file in my project, I have to add it also in CMakeLists.txt.
Now I'm trying to enable tha gcc compiler warnings (i.e. compiling with g++ -Wall ...).
Does Kdevelop have a compiler settings section, or I have to edit directly the Makefile or another CMake settings file?
You can add compiler flags in CMake by adding the following command to your CMakeLists.txt:
list( APPEND CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")

How do I activate C++ 11 in CMake?

When I try to run a CMake generated makefile to compile my program, I get the error that
range based for loops are not supported in C++ 98 mode.
I tried adding add_definitions(-std=c++0x) to my CMakeLists.txt, but it did not help.
I tried this too:
if(CMAKE_COMPILER_IS_GNUCXX)
add_definitions(-std=gnu++0x)
endif()
When I do g++ --version, I get:
g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
I have also tried SET(CMAKE_CXX_FLAGS "-std=c++0x"), which also does not work.
I do not understand how I can activate C++ 11 features using CMake.
CMake 3.1 introduced the CMAKE_CXX_STANDARD variable that you can use. If you know that you will always have CMake 3.1 or later available, you can just write this in your top-level CMakeLists.txt file, or put it right before any new target is defined:
set (CMAKE_CXX_STANDARD 11)
If you need to support older versions of CMake (quite unlikely these days), here is a macro I came up with that you can use:
macro(use_cxx11)
if (CMAKE_VERSION VERSION_LESS "3.1")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
endif ()
else ()
set (CMAKE_CXX_STANDARD 11)
endif ()
endmacro(use_cxx11)
The macro only supports GCC right now, but it should be straight-forward to expand it to other compilers.
Then you could write use_cxx11() at the top of any CMakeLists.txt file that defines a target that uses C++11.
CMake issue #15943 for clang users targeting macOS
If you are using CMake and clang to target macOS there is a bug that can cause the CMAKE_CXX_STANDARD feature to simply not work (not add any compiler flags). Make sure that you do one of the following things:
Use cmake_minimum_required to require CMake 3.0 or later, or
Set policy CMP0025 to NEW with the following code at the top of your CMakeLists.txt file before the project command:
# Fix behavior of CMAKE_CXX_STANDARD when targeting macOS.
if (POLICY CMP0025)
cmake_policy(SET CMP0025 NEW)
endif ()
The CMake command target_compile_features() is used to specify the required C++ feature cxx_range_for. CMake will then induce the C++ standard to be used.
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
add_executable(foobar main.cc)
target_compile_features(foobar PRIVATE cxx_range_for)
There is no need to use add_definitions(-std=c++11) or to modify the CMake variable CMAKE_CXX_FLAGS, because CMake will make sure the C++ compiler is invoked with the appropriate command line flags.
Maybe your C++ program uses other C++ features than cxx_range_for. The CMake global property CMAKE_CXX_KNOWN_FEATURES lists the C++ features you can choose from.
Instead of using target_compile_features() you can also specify the C++ standard explicitly by setting the CMake properties
CXX_STANDARD
and
CXX_STANDARD_REQUIRED for your CMake target.
See also my more detailed answer.
I am using
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
But if you want to play with C++11, g++ 4.6.1 is pretty old.
Try to get a newer g++ version.
The easiest way to set the Cxx standard is:
set_property(TARGET tgt PROPERTY CXX_STANDARD 11)
See the CMake documentation for more details.
On modern CMake (>= 3.1) the best way to set global requirements is:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
It translates to "I want C++11 for all targets, it's not optional, I don’t want to use any GNU or Microsoft extensions."
As of C++17, this still is IMHO the best way.
Source: Enabling C++11 And Later In CMake
As it turns out, SET(CMAKE_CXX_FLAGS "-std=c++0x") does activate many C++11 features. The reason it did not work was that the statement looked like this:
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs")
Following this approach, somehow the -std=c++0x flag was overwritten and it did not work. Setting the flags one by one or using a list method is working.
list( APPEND CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs")
For CMake 3.8 and newer you can use
target_compile_features(target PUBLIC cxx_std_11)
If you want the generation step to fail if the toolchain cannot adhere to this standard, you can make this required.
set_target_properties(target PROPERTIES CXX_STANDARD_REQUIRED ON)
If you want strict adherence to standard C++ i.e. avoid C++ extensions offered by your compiler (like GCC's -std=gnu++17), additionally set
set_target_properties(target PROPERTIES CXX_EXTENSIONS OFF)
This is documented in detail at An Introduction to Modern CMake -> Adding Features -> C++11 and Beyond. It also offers advice on how to achieve this on older versions of CMake if you're constrained to those.
The easiest way:
add_compile_options(-std=c++11)
This is another way of enabling C++11 support,
ADD_DEFINITIONS(
-std=c++11 # Or -std=c++0x
# Other flags
)
I have encountered instances where only this method works and other methods fail. Maybe it has something to do with the latest version of CMake.
Modern cmake offers simpler ways to configure compilers to use a specific version of C++. The only thing anyone needs to do is set the relevant target properties. Among the properties supported by cmake, the ones that are used to determine how to configure compilers to support a specific version of C++ are the following:
CXX_STANDARD sets the C++ standard whose features are requested to build the target. Set this as 11 to target C++11.
CXX_EXTENSIONS, a boolean specifying whether compiler specific extensions are requested. Setting this as Off disables support for any compiler-specific extension.
To demonstrate, here is a minimal working example of a CMakeLists.txt.
cmake_minimum_required(VERSION 3.1)
project(testproject LANGUAGES CXX )
set(testproject_SOURCES
main.c++
)
add_executable(testproject ${testproject_SOURCES})
set_target_properties(testproject
PROPERTIES
CXX_STANDARD 11
CXX_EXTENSIONS off
)
In case you want to always activate the latest C++ standard, here's my extension of David Grayson's answer, in light of the recent (CMake 3.8 and CMake 3.11) additions of values of 17 and 20 for CMAKE_CXX_STANDARD):
IF (CMAKE_VERSION VERSION_LESS "3.8")
SET(CMAKE_CXX_STANDARD 14)
ELSEIF (CMAKE_VERSION VERSION_LESS "3.11")
SET(CMAKE_CXX_STANDARD 17)
ELSE()
SET(CMAKE_CXX_STANDARD 20)
ENDIF()
# Typically, you'll also want to turn off compiler-specific extensions:
SET(CMAKE_CXX_EXTENSIONS OFF)
(Use that code in the place of set (CMAKE_CXX_STANDARD 11) in the linked answer.)
What works for me is to set the following line in your CMakeLists.txt:
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
Setting this command activates the C++11 features for the compiler and after executing the cmake .. command, you should be able to use range based for loops in your code and compile it without any errors.
I think just these two lines are enough.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
The modern way is to specify the minimum required standard to C++11 with:
target_compile_features(foo PUBLIC cxx_std_11)
This way:
CMake can honor default C++ standard of the compiler if it's greater than C++11
You can clearly specify whether C++ standard is required at build time, consume time, or both. This is nice for libraries.
Public compile features are propagated to downstream targets, so it comes for free in those targets even if they don't directly use this feature.
Users can externally set another C++ standard (more recent basically), with CMAKE_CXX_STANDARD, either from command line or CMake presets. If you hardcode CMAKE_CXX_STANDARD in a CMakeLists, nobody can override the C++ standard without editing your CMakeLists, which is not very pleasant.
It requires CMake >= 3.8
You can use the following. This automatically modifies the feature based on your environment.
target_compile_features(your_target INTERFACE cxx_std_20)
For example,
on Gnu/Linux the following adds -std=gnu++20
on Windows with Clang/Ninja it becomes -std=c++20
on Windows with MSVC it becomes /std=c++20
So you support as many as environments possible.
In case you stumble on that same error using cmake as i did.
You need to set
set (CMAKE_CXX_STANDARD 11)
to activate threading because it is only supported from c++11 ++
hope that helps
OS X and Homebrew LLVM related:
Don't forget to call cmake_minimum_required(VERSION 3.3) and project() after it!
Or CMake will insert project() implicitly before line 1, causing trouble with Clang version detection and possibly other sorts of troubles. Here is a related issue.

Pass option to cmake for future option to crosscompilation (CROSS_COMPILE)

IF(UNIX)
# CROSS COMPILATION! ON/OFF
#SET(CMAKE_C_COMPILER /home/username/projects/buildroot/output/host/usr/bin/arm-linux-gcc)
#SET(CMAKE_CXX_COMPILER /home/username/projects/buildroot/output/host/usr/bin/arm-linux-g++)
#SET(CMAKE_C_COMPILER /home/username/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-eabi-gcc)
#SET(CMAKE_CXX_COMPILER /home/username/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-eabi-g++)
here is what I do now for cross-compilation. I want to add option to run it alike that:
make CROSS_COMPILE=~/projects/buildroot/output/host/usr/bin/arm-linux-
and if I do not path CROSS_COMPILE to make (not to cmake) it must use system defaults so cmake must path this option to makefile. How can I make it?
Buildroot generates a CMake toolchain file for you. Depending on your Buildroot, it might be directly in the output directory, or in output/host/usr/share/buildroot. The file is named toolchainfile.cmake. Then to build your CMake applications, do:
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/buildroot/output/host/usr/share/buildroot/toolchainfile.cmake
This file contains all the definitions of the cross-compiler paths, pkg-config environment variables, headers and libraries location, etc.
For the simplest method, do this:
SET(CMAKE_C_COMPILER $(CROSS_COMPILE)gcc)
SET(CMAKE_CXX_COMPILER $(CROSS_COMPILE)g++)
When the CROSS_COMPILE variable is passed to make, it will be substituted with the cross compiler path.
Now, the proper way. Ideally, the CROSS_COMPILE variable should be defined when CMake is run as it is meant to be cross-platform. Using the first solution could break if other CMake generators are used.
This can be done as:
IF(UNIX)
SET(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc)
SET(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++)
Then define the variable:
cmake -G "Unix Makefiles" -DCROSS_COMPILE=~/projects/buildroot/output/host/usr/bin/arm-linux-
In this case, CMake will generate proper build files, based on whether CROSS_COMPILE is defined or not.

Resources