cmake with multiple c files and header files - c

I have some trouble in using cmake.
I have five files as below.
list.c
list.h
spooky-c.c
spooky-c.h
main.c
And
list.c #includes list.h
spooky-c.c #includes spooky-c.h
main.c #includes spooky-c.c and list.c
I tried to make CMakeLists.txt as follows
cmake_minimum_required(VERSION 3.0)
project(Project_1 C)
set(CMAKE_C_STANDARD 99)
include_directories(include)
file(GLOB SOURCES "src/*.c")
add_executable(Project_1 ${SOURCES})
with following directory structure
list.h and spooky-c.h are in include/ folder
list.c, spooky-c.c, main.c are in src/ folder
But make doesn't work.
How should the CMakeLists.txt look like?
With the help of #Someprogrammerdude, I changed main.c to #include list.h and spooky-c.h.
cmake works as follows
(base) joo#joo:~/CLionProjects/Advanced_Programming/Project_1 (copy)/build$ cmake ..
-- The C compiler identification is GNU 7.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/joo/CLionProjects/Advanced_Programming/Project_1 (copy)/build
But following error occurs.
(base) joo#joo:~/CLionProjects/Advanced_Programming/Project_1 (copy)/build$ make
Scanning dependencies of target Project_1
[ 33%] Building C object CMakeFiles/Project_1.dir/src/list.c.o
[ 66%] Building C object CMakeFiles/Project_1.dir/src/spooky-c.c.o
[100%] Linking C executable Project_1
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
CMakeFiles/Project_1.dir/build.make:120: recipe for target 'Project_1' failed
make[2]: *** [Project_1] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/Project_1.dir/all' failed
make[1]: *** [CMakeFiles/Project_1.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
#Someprogrammerdude
Thank you. I forgot to move main.c to src folder.
Now it works.

Related

Error in target_link_libraries when linking GSL in CLion CMakeLists.xt

I'm trying to use a C++ code in CLion which relies on the external C library GSL.
I created a CMakeLists.txt file as:
cmake_minimum_required(VERSION 3.20)
project(untitled)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_COMPILER /usr/local/Cellar/gcc/11.1.0_1/bin/g++-11)
set(CMAKE_CXX_FLAGS " -std=c++17 -mpopcnt -L/usr/local/lib")
include_directories(${PROJECT_BINARY_DIR}/Include /usr/local/include)
add_executable(untitled main.cpp)
find_package(GSL REQUIRED)
include_directories(${GSL_INCLUDE_DIR})
target_link_libraries(untitled main.cpp GSL::gsl)
but when I compile it I get the follwing error:
[ 50%] Linking CXX executable untitled
ld: library not found for -lmain.cpp
collect2: error: ld returned 1 exit status
make[3]: *** [untitled] Error 1
make[2]: *** [CMakeFiles/untitled.dir/all] Error 2
make[1]: *** [CMakeFiles/untitled.dir/rule] Error 2
make: *** [untitled] Error 2
Any suggestion on what could cause this?
The problem in my code in CMakeLists.txt was simple and trivial, I just did not see it.
In fact, had to remove the 'main.cpp' declaration within target_link_libraries.
cmake_minimum_required(VERSION 3.20)
project(untitled)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
add_executable(untitled main.cpp)
find_package(GSL REQUIRED)
include_directories(${GSL_INCLUDE_DIR})
target_link_libraries(untitled GSL::gsl)
This code worked.
result: 5.05537 0.401813 0.150471
error : 0.0553737 0.00181308 0.000470529
Process finished with exit code 0

CMakeLists reports error: ld:cannot find -l

Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.14)
project(testlib C)
set(CMAKE_C_STANDARD 99)
include_directories(/usr/local/include/)
find_library(iconv_lib iconv)
add_executable(testlib library.c)
target_link_libraries(testlib libiconv.a)
In this folder /usr/local/include/ are the files:
iconv.h localcharset.h
The CMake reports the error:
====================[ Build | testlib | Debug ]=================================
D:\.CLion2019.2\system\cygwin_cmake\bin\cmake.exe --build /cygdrive/d/project/c/testlib/cmake-build-debug --target testlib -- -j 4
Scanning dependencies of target testlib
[ 50%] Building C object CMakeFiles/testlib.dir/library.c.o
[100%] Linking C executable testlib.exe
/usr/lib/gcc/x86_64-pc-cygwin/7.4.0/../../../../x86_64-pc-cygwin/bin/ld: cannot find -liconv
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/testlib.dir/build.make:84: testlib.exe] Error 1
make[2]: *** [CMakeFiles/Makefile2:76: CMakeFiles/testlib.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/testlib.dir/rule] Error 2
make: *** [Makefile:118: testlib] Error 2
It seems like you are not using the library located by find_library(), if it is actually found. If the library is not found, you can add search paths to tell CMake where to find this library:
find_library(iconv_lib
NAMES iconv
PATHS /path/containing/your/iconv/lib
)
Finally, use the iconv_lib variable you defined when calling target_link_libraries(), like this:
target_link_libraries(testlib PUBLIC ${iconv_lib})

Using cmake with a shared (dynamic) library

I'm trying to use a simple shared library that I made with a file that just contains a main method.
I first ran cmake . which worked fine and didn't return any errors.
Then I ran make but got this error:
$ make
Scanning dependencies of target myprog
[ 50%] Building C object CMakeFiles/myprog.dir/main.c.o
[100%] Linking C executable myprog.exe
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lhello-user
collect2: error: ld returned 1 exit status
clang-3.8: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)
make[2]: *** [CMakeFiles/myprog.dir/build.make:95: myprog.exe] Error 1
make[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/myprog.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
The CMakeLists.txt file
cmake_minimum_required(VERSION 2.8.8)
project(LIB_EXAMPLE)
set(CMAKE_C_COMPILER clang)
add_executable(myprog main.c)
target_link_libraries(myprog hello-user)
The library exists inside of /usr/local/lib/ as libhello-user.dll.a
Note: Im using Cygwin for cmake and make
Turning my comment into an answer
See CMake/Tutorials/Exporting and Importing Targets.
You either have:
to name a full path for the library
CMake is not searching for it automatically
you would have to add something like find_library(_lib_path NAMES hello-user)
or - better - put those into an IMPORTED target
cmake_minimum_required(VERSION 2.8.8)
project(LIB_EXAMPLE)
add_library(hello-user SHARED IMPORTED GLOBAL)
set_target_properties(
hello-user
PROPERTIES
IMPORTED_LOCATION /usr/local/lib/libhello-user.dll
IMPORTED_IMPLIB /usr/local/lib/libhello-user.dll.a
)
add_executable(myprog main.c)
target_link_libraries(myprog hello-user)

CMAKE no rule to make target for internal shared library

I wrote a cmake file that builds two shared library a vector3.c and a matrix4.c
The matrix4 depends on the vector3, if I run my cmake project and only build the vector3 shared library it builds just fine, when I add the matrix4 shared library I get a cmake error. No rule to make target.
The folder structure
core_math
------CMakeLists.txt
-common/
------common_structs.h
-matrix4/
------CMakeLists.txt
------matrix4/src/matrix4_scalar.c
------matrix4/headers/matrix4_scalar.h
-vector3/
-------CMakeLists.txt
-------vector3/src/vector3_scalar.c
-------vector3/headers/vector3_scalar.h
core_math/CMakeLists.txt
PROJECT(core_math)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
ADD_SUBDIRECTORY(vector3_scalar)
ADD_SUBDIRECTORY(matrix4_scalar)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY $(CMAKE_BINARY_DIR)/static_lib)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY $(CMAKE_BINARY_DIR)/shared_lib)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY $(CMAKE_BINARY_DIR)/bin)
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
core_math/vector3/CMakeLists.txt
PROJECT(vector3_scalar)
SET(CMAKE_MACOSX_RPATH 1)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../common)
SET(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../common/common_structs.h)
SET(SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/vector3_scalar.c ${HEADER_FILES})
ADD_LIBRARY(vector3_scalar SHARED ${SRC_FILES})
core_math/matrix4_scalar/CMakeLists.txt
PROJECT(matrix4_scalar)
SET(CMAKE_MACOSX_RPATH 1)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../common
${CMAKE_CURRENT_SOURCE_DIR}/../vector3_scalar)
SET(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../common/common_structs.h
${CMAKE_CURRENT_SOURCE_DIR}/../vector3_scalar/headers/vector3_scalar.h
${CMAKE_CURRENT_SOURCE_DIR}/headers/matrix4_scalar.h)
SET(SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/matrix4_scalar.c ${HEADER_FILES})
ADD_LIBRARY(matrix4_scalar SHARED ${SRC_FILES})
TARGET_LINK_LIBRARIES(matrix4_scalar vector3_scalar)
build error
-- Build files have been written to: /Users/blubee/MATH/project/build
Scanning dependencies of target vector3_scalar
[ 25%] Building C object source/core_math/vector3_scalar/CMakeFiles/vector3_scalar.dir/sr
c/vector3_scalar.c.o
[ 50%] Linking C shared library $(CMAKE_BINARY_DIR)/lib/libvector3_scalar.dylib
[ 50%] Built target vector3_scalar
Scanning dependencies of target matrix4_scalar
[ 75%] Building C object source/core_math/matrix4_scalar/CMakeFiles/matrix4_scalar.dir/sr
c/matrix4_scalar.c.o
make[2]: *** No rule to make target `source/core_math/vector3_scalar//Users/blubee/MATH/pr
oject/build/lib/libvector3_scalar.dylib', needed by `source/core_math/matrix4_scalar//Use
rs/blubee/MATH/project/build/lib/libmatrix4_scalar.dylib'. Stop.
make[1]: *** [source/core_math/matrix4_scalar/CMakeFiles/matrix4_scalar.dir/all] Error 2
make: *** [all] Error 2
if I remove the target_link_libraries from the matrix4_scalar cmakelists.txt file then I get undefined symbols error instead.
Undefined symbols for architecture x86_64:
"_vec3_deg2rad", referenced from:
_mat4_rotate in matrix4_scalar.c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [source/core_math/matrix4_scalar//Users/blubee/MATH/project/build/lib/libmatr
ix4_scalar.dylib] Error 1
make[1]: *** [source/core_math/matrix4_scalar/CMakeFiles/matrix4_scalar.dir/all] Error 2
make: *** [all] Error 2
I have done some testing with your code and could reproduce the problem.
It's related to having used $(...) brackets for variable dereferencing in the SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ...) command. I've changed $(CMAKE_BINARY_DIR) to ${CMAKE_BINARY_DIR} and everything works fine:
> cmake --build .
-- Configuring done
-- Generating done
-- Build files have been written to: build
Scanning dependencies of target vector3_scalar
[ 25%] Building C object vector3_scalar/CMakeFiles/vector3_scalar.dir/src/vector3_scalar.c.o
[ 50%] Linking C shared library ../shared_lib/libvector3_scalar.dylib
[ 50%] Built target vector3_scalar
Scanning dependencies of target matrix4_scalar
[ 75%] Building C object matrix4_scalar/CMakeFiles/matrix4_scalar.dir/src/matrix4_scalar.c.o
[100%] Linking C shared library ../shared_lib/libmatrix4_scalar.dylib
[100%] Built target matrix4_scalar
References
CMake Error at CMakeLists.txt:30 (project): No CMAKE_C_COMPILER could be found
What's the CMake syntax to set and use variables?
[CMake] Trouble setting LIBRARY_OUTPUT_DIRECTORY
Custom Directory for CMake Library Output

cmake set linker flags for boost

I'm trying to compile a boost tutorial example from http://www.boost.org/doc/libs/1_36_0/doc/html/boost_asio/tutorial/tuttimer1.html.
My CMakeLists.txt looks like the following:
project(boost)
add_executable(timer1 timer1.cpp)
set_target_properties(timer1 PROPERTIES LINK_FLAGS -lboost_system,-lpthread)
trying to build the whole thing with cmake, I get:
/var/www/C++/boost/build$ make
-- Configuring done
-- Generating done
-- Build files have been written to: /var/www/C++/boost/build
Scanning dependencies of target timer1
[100%] Building CXX object CMakeFiles/timer1.dir/timer1.cpp.o
Linking CXX executable timer1
/usr/bin/ld: cannot find -lboost_system,-lpthread
collect2: ld returned 1 exit status
make[2]: *** [timer1] Błąd 1
make[1]: *** [CMakeFiles/timer1.dir/all] Błąd 2
make: *** [all] Błąd 2
But when I run:
g++ timer1.cpp -lboost_system -lpthread -o timer1
manually, everything works fine. Can someone please point me on what do I do wrong?
PS
When I try to use solution described in Turning on linker flags with CMake, I add to cmake the following lines:
set(CMAKE_SHARED_LINKER_FLAGS "-lboost_system,-lpthread")
set(CMAKE_MODULE_LINKER_FLAGS "-lboost_system,-lpthread")
set(CMAKE_EXE_LINKER_FLAGS "-lboost_system,-lpthread")
and I get the same error as above.
I strongly suggest that you use the CMake integrated FindPackage. CMake will find boost and pthreads for you.
Your CMakeLists.txt should look like this:
find_package( Boost COMPONENTS thread system filesystem REQUIRED ) #whatever libs you need
include_directories( ${Boost_INCLUDE_DIRS} )
find_package( Threads )
In the subfolder src:
set( LIBS_TO_LINK
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)
target_link_libraries( myApp
${LIBS_TO_LINK}
)
/usr/bin/ld: cannot find -lboost_system,-lpthread
Here the linker is looking for a library libboost_system,-lpthread.so. It is exceedingly unlikely that such a library exists on any UNIX system.
You probably want:
set(CMAKE_EXE_LINKER_FLAGS "-lboost_system -lpthread")

Resources