I'm trying to translate a Makefile into CMakeLists.txt.
Makefile which works
fb1-5: fb1-5.l fb1-5.y
bison -d fb1-5.y
flex fb1-5.l
cc -o $# fb1-5.tab.c lex.yy.c -lfl
CMakeLists.txt attempt
cmake_minimum_required(VERSION 3.7)
project(calc)
set(CMAKE_C_STANDARD 99)
FIND_PACKAGE(BISON REQUIRED)
SET(BisonOutput ${CMAKE_SOURCE_DIR}/parser.c)
IF(BISON_FOUND)
ADD_CUSTOM_COMMAND(
OUTPUT ${BisonOutput}
COMMAND ${BISON_EXECUTABLE}
-d
${CMAKE_SOURCE_DIR}/fb1-5.y
COMMENT "Generating parser.c"
)
ENDIF()
FIND_PACKAGE(FLEX REQUIRED)
SET(FlexOutput ${CMAKE_SOURCE_DIR}/scanner.c)
IF(FLEX_FOUND)
ADD_CUSTOM_COMMAND(
OUTPUT ${FlexOutput}
COMMAND ${FLEX_EXECUTABLE}
${CMAKE_SOURCE_DIR}/fb1-5.l
COMMENT "Generating fb1-5.l"
)
ENDIF()
ADD_LIBRARY(calc ${BisonOutput} ${FlexOutput})
It says it finds bison and flex in clion
-- Found BISON: /usr/bin/bison (found version "3.0.4")
-- Found FLEX: /usr/bin/flex (found version "2.6.0")
But my CMake script won't generate an executable. How should I define "executable" and how can I make the CMake build script work in CLion?
But my CMake script won't generate an executable. How should I define "executable" and how can I make the CMake build script work in CLion?
I think you should at least do something like this:
add_executable(fb1-5
${BisonOutput}
${FlexOutput}
)
See add_executable.
Related
This question already has answers here:
How to config cmake for strip file
(4 answers)
Closed 12 months ago.
why is cmake producing a binary with debug_info and not stripped?
here is my CMakeLists.txt
cmake_minimum_required(VERSION 3.22)
# project name
project(c-program)
set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(CMAKE_C_STANDARD "90")
set(CMAKE_C_STANDARD_REQUIRED true)
set(CMAKE_C_FLAGS "-ansi -Wall")
set(CMAKE_C_FLAGS_DEBUG "-g3 -ggdb3")
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
add_executable(c-program c-program.c)
i build like this from the project root folder
$ cmake -S . -B build/release -DCMAKE_BUILD_TYPE=Release
$ cmake --build build/release
when running
$ file build/release/c-program
i get
build/release/c-program: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, with debug_info, not stripped
i am confused about how debug/release builds are supposed to work, and nothing in the cmake tutorial guides or docs or otherwise online is helping me figure out why this is happening
there are some issues with setting flags in CMakeLists.txt, so adding and using a toolchain file helped, and setting appropriate CMAKE_<LANG>_FLAGS_<CONFIG>_INIT vars in the toolchain file. also, the linker is adding debug info. adding -s flag to cmake release flags, and adding -Wl,--strip-debug to linker flags is what i was looking for
here is my final CMakeLists.txt and toolchain files
#CMakeLists.txt
cmake_minimum_required(VERSION 3.22)
# set toolchain file
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain.cmake"
CACHE PATH "Path to the desired toolchain file.")
# project name
project(c-program C)
add_executable(c-program c-program.c)
# toolchain.cmake
# CMake toolchain file
# c compiler and standard
set(CMAKE_C_COMPILER "/usr/bin/gcc")
set(CMAKE_C_STANDARD "90")
set(CMAKE_C_STANDARD_REQUIRED YES)
# linker flags
set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,--strip-debug")
# cflags
set(CMAKE_C_FLAGS_INIT "-ansi -Wall")
# cflags for debug build
set(CMAKE_C_FLAGS_DEBUG_INIT "-g3 -ggdb3")
# cflags for release build
set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG -s")
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
I have a C application which is running on Raspberry Pi 3 and currently, I have to build it on PI with Cmake. I am trying to build it on Ubuntu machine. I have added a CMAKE_TOOLCHAIN_FILE as described here.
I could run cmake. -DCMAKE_TOOLCHAIN_FILE without any problem but the "make" command is not successful and it can not find a header file inside one of the external library: "mirsdrapi-rsp". The error message is:
fatal error: mirsdrapi-rsp.h: No such file or directory
#include "mirsdrapi-rsp.h"
^
compilation terminated.
I have created a folder named "lib" and have put the "libmirsdrapi-rsp.so" file inside it.
my CMakeLists.txt is as below:
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wextra -v -g -D_XOPEN_SOURCE")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Wextra -v ")
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-v")
set (SDR_API_PATH ${CMAKE_SOURCE_DIR}/lib)
include_directories (include ${SDR_API_PATH})
include_directories("${CMAKE_SOURCE_DIR}/lib")
find_library(mirslocation NAMES mirsdrapi-rsp HINTS ${SDR_API_PATH} NO_CMAKE_FIND_ROOT_PATH)
message(STATUS ${mirslocation})
add_library(mirs STATIC IMPORTED)
set_target_properties(mirs PROPERTIES IMPORTED_LOCATION ${mirslocation})
target_link_libraries (raspberryPiDaemon mirs)
target_link_libraries(raspberryPiDaemon m)
Cmake is printing the right path of the library mirsdrapi-rsp while running "find_library" and as I mentioned I am getting the error message just while running "make" command and not "cmake" command.
My content of CMAKE_TOOLCHAIN_FILE is as below:
# Define our host system
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
# Define the cross compiler locations
SET(CMAKE_C_COMPILER ${CMAKE_SOURCE_DIR}/../tools-master/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER ${CMAKE_SOURCE_DIR}/../tools-master/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc)
# Define the sysroot path for the RaspberryPi distribution in our tools folder
SET(CMAKE_FIND_ROOT_PATH ${CMAKE_SOURCE_DIR}/../tools-master/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/sysroot/SET)
# Use our definitions for compiler tools
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Search for libraries and headers in the target directories only
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
add_definitions(-Wall -std=c11)
Anybody knows how I can add the header file from mirsdrapi-rsp library to include path?
I guess that you're setting include_directories to the wrong path (it is set 2 times to ${CMAKE_SOURCE_DIR}/lib which must be the folder of libraries not the header files). Check again the correct location of the missing header file.
More precisely: you need to find the path of mirsdrapi-rsp.h and let CMake know it just like for find_library:
find_path(MIRSDRAPI_INCLUDE_DIRS NAMES mirsdrapi-rsp.h PATHS {proper-location})
if (MIRSDRAPI_INCLUDE_DIRS)
target_include_directories(raspberryPiDaemon PRIVATE ${MIRSDRAPI_INCLUDE_DIRS})
endif()
In addition, you can set the INTERFACE_INCLUDE_DIRECTORIES property to the library like this:
set_property(TARGET mirsdrapi-rsp APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MIRSDRAPI_INCLUDE_DIRS})
This way, target_include_directories might be unnecessary and target_link_directories should be enough.
How to execute a shell script using CMake? The command that should be run is my_script that should be executed after build. The CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(abc)
include_directories("/usr/lib/avr/include")
set(CMAKE_CURRENT_SOURCE_DIR /home/user/Desktop)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmcu=atmega8")
set(SOURCE_FILES main.c)
add_executable(abc ${SOURCE_FILES})
#not working ----->
add_custom_command(TARGET abc
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E my_script
)
DISCLAIMER
Yes, there are similar questions in SO here, here, here, etc; however, they don't give me a clear vision how this can be achieved.
You are invoking CMake with it's command-line tool mode which doesn't execute generic scripts or commands.
Instead do e.g.
add_custom_command(TARGET abc
POST_BUILD
COMMAND /bin/sh /path/to/my_script
)
I'm beginner with CMake and i would to compile my project with it.
I have the following CMakeLists.txt:
cmake_minimum_required (VERSION 2.6)
project (rt)
include_directories ("${PROJECT_BINARY_DIR}/src/")
include_directories ("${PROJECT_BINARY_DIR}/src/hook")
include_directories ("${PROJECT_BINARY_DIR}/src/light")
include_directories ("${PROJECT_BINARY_DIR}/src/move")
include_directories ("${PROJECT_BINARY_DIR}/src/object/inter")
include_directories ("${PROJECT_BINARY_DIR}/src/object/normal")
include_directories ("${PROJECT_BINARY_DIR}/src/option")
include_directories ("${PROJECT_BINARY_DIR}/src/parsing")
include_directories ("${PROJECT_BINARY_DIR}/src/ray")
include_directories ("${PROJECT_BINARY_DIR}/src/render")
include_directories ("${PROJECT_BINARY_DIR}/src/shadow")
include_directories ("${PROJECT_BINARY_DIR}/src/utils")
include_directories ("${PROJECT_BINARY_DIR}/lib/minilibx")
file(GLOB hook
"*.h"
"*.c"
)
file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/src/*.c)
#set (EXTRA_LIBS ${EXTRA_LIBS} ${X11_LIBRARIES} m)
add_executable (rt ${SRC_FILES})
target_link_libraries (rt ${EXTRA_LIBS} X11 Xext m ${PROJECT_BINARY_DIR}/lib/libmlx.a)
But when I run make, my static library minilibx won't compile. with errors that all the functions from the X11 and Xext libraries are undefined.
make VERBOSE=1 result:
Linking C executable rt
/usr/bin/cmake -E cmake_link_script CMakeFiles/rt.dir/link.txt --verbose=1
/usr/bin/cc CMakeFiles/rt.dir/src/move/translation.c.o CMakeFiles/rt.dir/src/move/rotation.c.o CMakeFiles/rt.dir/src/light/light.c.o CMakeFiles/rt.dir/src/option/option.c.o CMakeFiles/rt.dir/src/option/file_option.c.o CMakeFiles/rt.dir/src/render/render.c.o CMakeFiles/rt.dir/src/hook/control.c.o CMakeFiles/rt.dir/src/ray/eye.c.o CMakeFiles/rt.dir/src/ray/ray.c.o CMakeFiles/rt.dir/src/utils/my_strlen.c.o CMakeFiles/rt.dir/src/utils/my_strncpy.c.o CMakeFiles/rt.dir/src/object/inter/plan.c.o CMakeFiles/rt.dir/src/object/inter/cone.c.o CMakeFiles/rt.dir/src/object/inter/cylinder.c.o CMakeFiles/rt.dir/src/object/inter/sphere.c.o CMakeFiles/rt.dir/src/object/inter/tore.c.o CMakeFiles/rt.dir/src/object/normal/plan.c.o CMakeFiles/rt.dir/src/object/normal/cone.c.o CMakeFiles/rt.dir/src/object/normal/cylinder.c.o CMakeFiles/rt.dir/src/object/normal/sphere.c.o CMakeFiles/rt.dir/src/parsing/scene.c.o CMakeFiles/rt.dir/src/parsing/file_access.c.o CMakeFiles/rt.dir/src/parsing/str_tool.c.o CMakeFiles/rt.dir/src/shadow/shadow.c.o CMakeFiles/rt.dir/src/main.c.o -o rt -rdynamic -lX11 -lXext -lm lib/libmlx.a
and this is an example of errors:
lib/libmlx.a(mlx_init.o): In function mlx_int_deal_shm':
mlx_init.c:(.text+0x2a): undefined reference toXShmQueryVersion'
mlx_init.c:(.text+0x104): undefined reference to `XShmPixmapFormat'
How do I solve the undefined reference errors?
I have solved the problem, the order of libs are not correct.
I just link my lib before another lib. Et voilĂ :)
target_link_libraries (rt ${EXTRA_LIBS} ${PROJECT_BINARY_DIR}/lib/libmlx.a X11 Xext m)
CMake uses target_link_libraries to specify which libraries you link against.
In you case, it seems like you're linking against the correct libraries (target_link_libraries (rt ${EXTRA_LIBS} X11 Xext m ${PROJECT_BINARY_DIR}/lib/libmlx.a)), so my bet is they are not found.
Try running:
make VERBOSE=1
This will give you the gcc output. Paste the last couple of gcc instructions it generates here and we'll see why it didn't find your libs.