CMake-generated Makefile does not contain target - cmake

I'm using G++ MinGW for compiling. My Files :
main.cpp, linkedList.cpp, linkedList.h
My CMake file :
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project (Tutorial)
set(CMAKE_CXX_FLAGS "-Wall -std=c++11")
enable_testing()
include_directories(include)
add_executable(Tutorial
main.cpp
linkedList.cpp
linkedList.h
)
add_test(Tutorial tutorial)
The exact compile error from generated Makefile :
mingw32-make[2]: *** No rule to make target '../linkedList.h', needed by 'CMakeFiles/Tutorial.dir/main.cpp.obj'. Stop.
mingw32-make[1]: *** [CMakeFiles/Tutorial.dir/all] Error 2
mingw32-make: *** [all] Error 2
Gist for CMake generated Makefile

You target is Tutorial, not ../LinkedList.h
Go to your build directory and execute
make Tutorial

Related

How to add Ziplib library in Clion on Ubuntu

I'm trying to add ZipLip into my project using Clion on ubuntu, but I have this output:
====================[ Build | TryZip | Debug ]==================================
/home/david/Snap/clion-2019.2.4/bin/cmake/linux/bin/cmake --build
/home/david/CLionProjects/TryZip/cmake-build-debug --target TryZip -- -j 2
[ 13%] Built target bzip2
[ 31%] Built target zlib
[ 83%] Built target lzma
[ 95%] Built target ZipLib
Scanning dependencies of target TryZip
[ 97%] Linking CXX executable ../bin/TryZip
/usr/bin/ld: cannot find -lExternalLibrary/ZipLib
collect2: error: ld returned 1 exit status
CMakeFiles/TryZip.dir/build.make:102: recipe for target '../bin/TryZip' failed
make[3]: *** [../bin/TryZip] Error 1
CMakeFiles/Makefile2:109: recipe for target 'CMakeFiles/TryZip.dir/all' failed
make[2]: *** [CMakeFiles/TryZip.dir/all] Error 2
CMakeFiles/Makefile2:116: recipe for target 'CMakeFiles/TryZip.dir/rule' failed
make[1]: *** [CMakeFiles/TryZip.dir/rule] Error 2
Makefile:131: recipe for target 'TryZip' failed
make: *** [TryZip] Error 2
This is my Cmakefile.txt
cmake_minimum_required(VERSION 3.15)
project(TryZip)
if(BOOST_FILESYSTEM)
include_directories(${BOOST_INCLUDE_DIR})
link_directories(${BOOST_LIB_DIR})
add_definitions(-DUSE_BOOST_FILESYSTEM)
else()
if(MSVC)
add_definitions(-DFILESYSTEM_EXPERIMENTAL)
endif()
endif()
if(BOOST_FILESYSTEM)
if(UNIX)
find_package(Boost COMPONENTS system filesystem REQUIRED)
target_link_libraries(${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY})
endif()
endif()
add_subdirectory(ExternalLibrary/ZipLib)
link_libraries(ExternalLibrary/ZipLib)
include_directories(ExternalLibrary/ZipLib)
set(CMAKE_CXX_STANDARD 17)
add_executable(TryZip main.cpp ExternalLibrary/ZipLib/ZipFile.cpp)
target_link_libraries(TryZip ZipLib)
Can someone help me to solve this please?
My ZipLib folder is in the same folder as my cmakefile.txt file.
The call to link_libraries() appears to accept the wrong arguments in this case. The link_libraries() command takes arguments of existing CMake targets, or library names. It is also redundant with your target_link_libraries() call, as this already links ZipLib to TryZip.
Try removing the call to link_libraries(), as this CMake function is deprecated and its use is highly discouraged. The include_directories() call is similarly deprecated, in favor of the target-specific command, so consider using target_include_directories() instead.
Assuming your added sub-directory ExternalLibrary/ZipLib contains an additional CMakeLists.txt file for configuring the ZipLib target, you should not need to add the ZipFile.cpp file again. If this file is already compiled in the sub-directory into the target ZipLib, you do not need to compile it again into TryZip.
add_subdirectory(ExternalLibrary/ZipLib)
set(CMAKE_CXX_STANDARD 17)
add_executable(TryZip main.cpp)
target_include_directories(TryZip PRIVATE ExternalLibrary/ZipLib)
target_link_libraries(TryZip PRIVATE ZipLib)
EDIT: Based on your feedback, it appears ZipLib also depends on pthread but somehow it is not getting linked correctly. You might try to add the following to your ExternalLibrary/ZipLib/CMakeLists.txt file (if it doesn't already exist), to utilize CMake's FindThreads module:
find_package(Threads REQUIRED)
...
target_link_libraries(ZipLib PUBLIC Threads::Threads)

CMake, shared library linking fail

I'm currently getting used to cmake and I'm trying to compile a small project with a .so library linking.
My project is the following.
/
CMakeLists.txt
inc/
Als.h
src/
main.c
CMakeLists.txt
lib/
libals.so
build/
I'm compiling from the build directory with:
$ cmake ..
-- DIR:
-- Configuring done
-- Generating done
-- Build files have been written to: /home/julien/tmp/cmakeTest/build
And then:
$ make
Linking C executable cmakeTest
/usr/bin/ld: ne peut trouver -lals
collect2: error: ld returned 1 exit status
src/CMakeFiles/cmakeTest.dir/build.make:85: recipe for target 'src/cmakeTest' failed
make[2]: *** [src/cmakeTest] Error 1
CMakeFiles/Makefile2:75: recipe for target 'src/CMakeFiles/cmakeTest.dir/all' failed
make[1]: *** [src/CMakeFiles/cmakeTest.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2
The linker seems to be unable to find the libals.so file.
Here is the file /CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
PROJECT(cmaketest)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
INCLUDE_DIRECTORIES(
inc
)
ADD_SUBDIRECTORY(src)
get_directory_property(OUT_VAR LINK_DIRECTORIES)
message(STATUS "DIR: ${OUT_VAR}")
And here is the file /src/CMakeLists.txt:
PROJECT(cmakeTest)
FILE(
GLOB
${PROJECT_NAME}_Sources
*.c
)
INCLUDE_DIRECTORIES(
inc
inc
)
ADD_EXECUTABLE(
${PROJECT_NAME}
${${PROJECT_NAME}_Sources}
)
LINK_DIRECTORIES(
/home/julien/tmp/cmakeTest/lib/
)
TARGET_LINK_LIBRARIES(
${PROJECT_NAME}
als
pthread
)
Maybe I missed something but if I change the /src/CMakeLists.txt to:
PROJECT(cmakeTest)
FILE(
GLOB
${PROJECT_NAME}_Sources
*.c
)
INCLUDE_DIRECTORIES(
inc
inc
)
ADD_EXECUTABLE(
${PROJECT_NAME}
${${PROJECT_NAME}_Sources}
)
TARGET_LINK_LIBRARIES(
${PROJECT_NAME}
/home/julien/tmp/cmakeTest/lib/libals.so
pthread
)
The compilation is ok. Does someone know why the linker is unable to find libals.so when I'm giving him the good directory path to look in?
The LINK_DIRECTORIES functions seems not to be working.
Besides the solution you already have, and my solution in a comment, the problem you have with the CMake file shown is the order in which you invoke the CMake commands.
From the link_directories command reference:
The command will apply only to targets created after it is called.
[Emphasis mine]
You simply need to call link_directories before you call add_executable.

Adding static dependency in CMake

I've got an example project:
.
├── CMakeLists.txt
└── src
└── test1.f90
where test1.f90 uses a specific version of Lapack (therefore I can't use FindLAPACK).
I am trying to compile this using CMake:
cmake_minimum_required(VERSION 2.5)
project(TEST)
file(GLOB_RECURSE sources src/*.f90)
add_executable(cmake.x ${sources})
enable_language(Fortran)
set(CMAKE_Fortran_COMPILER_ID "IBM")
if(CMAKE_Fortran_COMPILER_ID MATCHES "IBM")
set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS)
MESSAGE(STATUS "IBM")
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-allow-multiple-definition ")
set(CMAKE_Fortran_COMPILER mpixlf2008_r)
set(debug "-C")
endif()
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} ${bounds}")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${dialect}")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
MESSAGE( STATUS "cmake_module_path: " ${CMAKE_MODULE_PATH})
If I run make VERBOSE=1 this results in:
...
[100%] Building Fortran object CMakeFiles/cmake.x.dir/src/test1.o
mpixlf2008_r -c /work/jias12/jias1217/lapack_test/src/test1.f90 -o CMakeFiles/cmake.x.dir/src/test1.o
** main === End of Compilation 1 ===
1501-510 Compilation successful for file test1.f90.
Linking Fortran executable cmake.x
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmake.x.dir/link.txt --verbose=1
mpixlf2008_r -Wl,-allow-multiple-definition CMakeFiles/cmake.x.dir/src/test1.o -o cmake.x
CMakeFiles/cmake.x.dir/src/test1.o:(.text+0x5c): undefined reference to `sgesv'
make[2]: *** [cmake.x] Error 1
make[2]: Leaving directory `/work/jias12/jias1217/lapack_test'
make[1]: *** [CMakeFiles/cmake.x.dir/all] Error 2
make[1]: Leaving directory `/work/jias12/jias1217/lapack_test'
make: *** [all] Error 2
This obviously doesn't work, because I didn't include LAPACK, which I then can do manually:
mpixlf2008_r -Wl,-allow-multiple-definition CMakeFiles/cmake.x.dir/src/test1.o -o cmake.x -L$LAPACK_LIB -L/bgsys/local/lib -llapack -lesslbg
Which works fine. How can I achieve this using CMake? I want to add -L$LAPACK_LIB -L/bgsys/local/lib -llapack -lesslbg to the linker after the *.o files. All I've managed is to add them as flags before the *.o files, which fails. I've look at a number of examples on the web, but I cannot find something which works in my case. This is the test1.f90.
This is in the folders:
> ls $LAPACK_LIB
libblas_extra.a libcblas.a liblapack.a liblapacke.a libtmglib.a
ls /bgsys/local/lib/
BGeic.pm BG.pm libesslbg.a libesslsmpbg.a
As Tsyvarev correctly mentioned:
What is wrong with target_link_libraries which links with the
libraries (meaning of flag -l) and link_directories which specifies
libraries search path (meaning of flag -L)?
Those hase to be called in the right order, which leads to:
cmake_minimum_required(VERSION 2.5)
project(TEST)
file(GLOB_RECURSE sources src/*.f90)
link_directories($ENV{LAPACK_LIB} /bgsys/local/lib)
enable_language(Fortran)
add_executable(cmake.x ${sources})
target_link_libraries(cmake.x lapack esslbg)

How can I make build failure of a custom target stop the building of a dependent target in CMake?

I am using CMake to build an application and a collection of plugins.
ADD_LIBRARY (plugin_X ...)
ADD_LIBRARY (plugin_Y ...)
ADD_LIBRARY (plugin_Z ...)
ADD_CUSTOM_TARGET (all_plugins)
ADD_DEPENDENCIES (all_plugins plugin_X plugin_Y plugin_Z)
ADD_EXECUTABLE (application ...)
ADD_DEPENDENCIES (application all_plugins)
The idea is that by running make application the plugins will be built as well.
My build scripts rely on make returning an error code if the build fails, but if one of the plugins fails to build, make application will still succeed.
How can I make the build of application fail if its dependencies fail?
On my box, it works correctly.
main.c
#include <stdio.h>
int main()
{
printf("Hello world!");
}
a.c
int test(){errorhere}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
ADD_LIBRARY (plugin_X a.c)
ADD_LIBRARY (plugin_Y a.c)
ADD_LIBRARY (plugin_Z a.c)
ADD_CUSTOM_TARGET (all_plugins)
ADD_DEPENDENCIES (all_plugins plugin_X plugin_Y plugin_Z)
ADD_EXECUTABLE (application main.c)
ADD_DEPENDENCIES (application all_plugins)
Make command
cmake -G "Unix Makefiles" ..
make application; echo $?
a.c:1: error: expected ‘;’ before ‘}’ token
make[3]: *** [CMakeFiles/plugin_X.dir/a.c.o] Error 1
make[2]: *** [CMakeFiles/plugin_X.dir/all] Error 2
make[1]: *** [CMakeFiles/application.dir/rule] Error 2
make: *** [application] Error 2
2

CMake install: installing configuration files

I want CMake to make install rules for me which also automatically install configuration and other things. I looked at this question, but adding:
add_executable(solshare_stats.conf solshare_stats.conf)
to my CMakeLists.txt file only gave me warnings and errors:
CMake Error: CMake can not determine linker language for target:solshare_stats.conf
CMake Error: Cannot determine link language for target "solshare_stats.conf".
...
make[2]: *** No rule to make target `CMakeFiles/solshare_stats.conf.dir/build'. Stop.
make[1]: *** [CMakeFiles/solshare_stats.conf.dir/all] Error 2
make: *** [all] Error 2
How do I add configuration, init and/or logfiles to CMake install rules?
Here is my complete CMakeLists.txt file:
project(solshare_stats)
cmake_minimum_required(VERSION 2.8)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST} )
add_executable(solshare_stats.conf solshare_stats.conf)
target_link_libraries(solshare_stats mysqlcppconn)
target_link_libraries(solshare_stats wiringPi)
if(UNIX)
if(CMAKE_COMPILER_IS_GNUCXX)
SET(CMAKE_EXE_LINKER_FLAGS "-s")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wall -std=c++0x")
endif()
install(TARGETS solshare_stats DESTINATION /usr/bin COMPONENT binaries)
install(TARGETS solshare_stats.conf DESTINATION /etc/solshare_stats COMPONENT config)
endif()
The .conf file should be included in the add_executable where you define your executable target, not in a separate call:
add_executable(${PROJECT_NAME} ${SRC_LIST} solshare_stats.conf)
Then you need to use install(FILE ...) rather than install(TARGET ...):
install(TARGETS solshare_stats DESTINATION /usr/bin COMPONENT binaries)
install(FILES solshare_stats.conf DESTINATION etc/solshare_stats COMPONENT config)
By doing
add_executable(${PROJECT_NAME} ${SRC_LIST})
add_executable(solshare_stats.conf solshare_stats.conf)
you're saying you want to create 2 executables, one called "solshare_stats" and another called "solshare_stats.conf".
The second target's only source file is the actual file "solshare_stats.conf". Since none of the source files in this target have a suffix which gives an idea about the language (e.g ".cc" or ".cpp" implies C++, ".asm" implies assembler), no language can be deduced, hence the CMake error.