How to create CMakeLists for this make file [duplicate] - cmake

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

Related

CMake having multiple executables throws me an error

I'm having some trouble with cmake: I'm using cmake for my school project and there is a bonus part but we have to compile another executable for the bonus part, and I tried this:
cmake_minimum_required(VERSION 3.10)
project(philosophers)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_COMPILER /usr/bin/clang)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_FLAGS "-Wall -Wextra -Werror")
set(CMAKE_EXE_LINKER_FLAGS "-lpthread")
set(LIBFT ${CMAKE_CURRENT_SOURCE_DIR}/lib/libft42/libft.a)
add_custom_command(OUTPUT ${LIBFT}
COMMAND make
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libft42)
link_libraries(philo_bonus ${LIBFT})
link_libraries(philo ${LIBFT})
aux_source_directory(src SRC)
aux_source_directory(src_bonus SRC_BONUS)
add_executable(philo ${SRC} ${LIBFT})
add_executable(philo_bonus ${SRC_BONUS} ${LIBFT})
target_include_directories(philo
PUBLIC inc
PUBLIC lib/libft42/inc)
target_include_directories(philo_bonus
PUBLIC inc_bonus
PUBLIC lib/libft42/inc)
I removed include_directories and replaced it with target_include_directories because I want my two projects to have separate includes, but when I try to cmake -Bbuild -H., it says:
CMake Error at CMakeLists.txt:23 (add_executable):
Target "philo_bonus" links to itself.
CMake Error at CMakeLists.txt:22 (add_executable):
Target "philo" links to itself.
CMake Error: Cannot determine link language for target "philo_bonus".
CMake Error: CMake can not determine linker language for target: philo_bonus
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
I don't understand what happened here, I changed nothing in add_executable and it worked fine before I added another.

How to get cmake generate -std=c++14 flag for qcc compiler

I'm trying to cross compile some c++ library for QNX neutrino using cmake. In CMakeLists.txt file I specified CMAKE_CXX_STANDARD 14 required, but the resulting compiler command line does not contain the -std=c++14 option.
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
I've tried using target compile features:
target_compile_features(my_library PRIVATE cxx_std_14)
but that gives me the following error:
CMake Error at CMakeLists.txt:53 (target_compile_features):
target_compile_features no known features for CXX compiler
"QCC"
version 5.4.0.
When I'm using check_cxx_compiler_flag feature, it seems to recognize the option:
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-std=c++14 CXX14_SUPPORT)
if(CXX14_SUPPORT)
message("c++14 support found")
else()
message("c++14 unsupported")
endif()
This outputs message
c++14 support found
Running qcc manually it accepts the -std=c++14 option just fine and the code using std::make_unique compiles just fine.
Also using the native compiler (Ubuntu 18.04, gcc) everything work fine with cmake generated makefiles. make VERBOSE=1 displays the following command line (I removed some directories):
/usr/local/bin/c++ -Dshm_transfer_EXPORTS -I... -fPIC -std=gnu++14 -o CMakeFiles/shm_transfer.dir/src/SharedMemoryTransfer.cpp.o -c .../SharedMemoryTransfer.cpp
as opposed to the command line using qcc toolchain:
.../qnx700/host/linux/x86_64/usr/bin/qcc -lang-c++ -Vgcc_ntox86_64 -lang-c++ -Dshm_transfer_EXPORTS -I... -fPIC -o CMakeFiles/shm_transfer.dir/src/SharedMemoryTransfer.cpp.o -c .../SharedMemoryTransfer.cpp
I would have expected the cmake command to recognize that qcc supports the -std=c++14 option and generates the corresponding command lines because of the CMAKE_CXX_STANDARD setting.
Use
set_property(TARGET ${PROJECT_NAME} PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
. Using this you can stick the compiler setting to the target, while global flags are dis encouraged and can be overwritten by other cmake consumers. This the reason I assume why the deprecated set(CMAKE_CXX_STANDARD 14) did not help you: I can not see your full CMakeLists.txt and bet you have many sub folders and other targets, which could reset the CMAKE_CXX_STANDARD them selfs. Also make sure of the ordering of the CMake commands.
And you can replace ${PROJECT_NAME} with my_library if you want.
add_compile_options(-std=gnu++14)
Add this to your project level CMakeLists.txt file, not in toolchain.

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.

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