How to add Ziplib library in Clion on Ubuntu - cmake

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)

Related

Issues with linking GLFW to the executable with CMake

I am currently trying to link the GLFW library with my executable files in CLion. After hours of research and trial & error, I am stuck. I am using find_package() to locate my GLFW library. For some reason my FindGLFW.cmake file seems to correctly locate the library in /usr/local/lib/libglfw.a when using find_library(), but my CMakeLists.txt returns empty with find_package(). I don't really understand how that's possible. Could someone help me out?
CMakeLists.txt:
cmake_minimum_required(VERSION 3.15)
project(learnopengl)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMake)
find_package(glfw 3.3 REQUIRED)
message(STATUS "(CMakeLists.txt) GLFW: [${glfw}]")
if (NOT glfw)
message(SEND_ERROR "(CMakeLists) Did not find glfw_library")
endif()
add_executable(learnopengl src/main.cpp)
target_link_libraries(learnopengl glfw)
FindGLFW.cmake
find_library( GLFW_LIBRARY
NAMES
glfw3 glfw
PATHS
${GLFW_LOCATION}/lib
$ENV{GLFW_LOCATION}/lib
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
NO_DEFAULT_PATH
DOC "The GLFW library"
)
message(STATUS "(FindGLFW.cmake) GLFW_INCLUDE_DIR: [${GLFW_INCLUDE_DIR}]")
message(STATUS "(FindGLFW.cmake) GLFW_LIB: [${GLFW_LIBRARY}]")
if (NOT GLFW_LIBRARY)
message(SEND_ERROR "(FindGLFW.cmake) Did not find glfw_library")
Output when running cmake ..
-- (FindGLFW.cmake) GLFW_INCLUDE_DIR: [/usr/local/include]
-- (FindGLFW.cmake) GLFW_LIB: [/usr/local/lib/libglfw3.a]
-- (CMakeLists.txt) GLFW: []
CMake Error at CMakeLists.txt:12 (message):
(CMakeLists) Did not find glfw_library
When I tried to directly include find_library() in my CMakeLists.txt instead, it did locate the library, but when I tried to link it with my executable, I got a linker error saying it couldn't locate the library:
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(learnopengl)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMake)
find_library( GLFW_LIBRARY
NAMES
glfw3 glfw
PATHS
${GLFW_LOCATION}/lib
$ENV{GLFW_LOCATION}/lib
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
NO_DEFAULT_PATH
DOC "The GLFW library"
)
message(STATUS "(FindGLFW.cmake) GLFW_LIB: [${GLFW_LIBRARY}]")
if (NOT GLFW_LIBRARY)
message(SEND_ERROR "(CMakeLists.txt) Did not find glfw_library")
endif()
add_executable(learnopengl src/main.cpp)
target_link_libraries(learnopengl GLFW_LIBRARY)
Output:
~/dev/projects/opengl/learnopengl/build  cmake ..
-- (CMakeLists.txt) GLFW_LIB: [/usr/local/lib/libglfw3.a]
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/Philipp/dev/projects/opengl/learnopengl/build
~/dev/projects/opengl/learnopengl/build  cmake --build .
[ 50%] Linking CXX executable learnopengl
ld: library not found for -lGLFW_LIBRARY
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [learnopengl] Error 1
make[1]: *** [CMakeFiles/learnopengl.dir/all] Error 2
make: *** [all] Error 2
I would really appreciate some hints as to what I am doing wrong. I can't see why it wouldn't locate/link the library correctly.
Thank you!
In cmake, arguments are case sensitive, so find_package should be
find_package(GLFW 3.3 REQUIRED)
Linker problem can be found easily in the logs. You are trying to link -lGLFW_LIBRARY, however what you want to link is GLFW_LIBRARY's value, /usr/local/lib/libglfw3.a .
target_link_libraries(learnopengl ${GLFW_LIBRARY})

multiple definition of 'CGAL::Surface_mesh_parameterization::get_error_message(int)'

I am able to use CGAL surface mesh parametrization with given examples easily. Which means that CGAL is installed properly and is functional.
Ways to reproduce error:
Create a empty main file
Create a class file with appropriate modifications to CGAL square_border_parametrize.cpp
After I do cmake . and make this is the output
Scanning dependencies of target Main
[ 33%] Building CXX object CMakeFiles/Main.dir/SBP.cpp.o
:0:15: warning: missing whitespace after the macro name
:0:15: warning: missing whitespace after the macro name
[ 66%] Building CXX object CMakeFiles/Main.dir/main.cpp.o
:0:15: warning: missing whitespace after the macro name
:0:15: warning: missing whitespace after the macro name
[100%] Linking CXX executable Main
CMakeFiles/Main.dir/main.cpp.o: In function _mm_getcsr()':
/usr/local/include/CGAL/Interval_nt.h:202: multiple definition ofCGAL::Surface_mesh_parameterization::get_error_message(int)'
CMakeFiles/Main.dir/SBP.cpp.o:/usr/local/include/CGAL/Surface_mesh_parameterization/Error_code.h:53: first defined here
collect2: error: ld returned 1 exit status
CMakeFiles/Main.dir/build.make:450: recipe for target 'Main' failed
make[2]: * [Main] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/Main.dir/all' failed
make[1]: * [CMakeFiles/Main.dir/all] Error 2
Makefile:140: recipe for target 'all' failed
make: *** [all] Error 2
I am not able to find any multiple definition for CGAL::Surface_mesh_parameterization::get_error_message(int). My CMakeLists.txt file looks like this:
cmake_minimum_required (VERSION 2.8 FATAL_ERROR)
PROJECT(LSCM)
FIND_PACKAGE( OpenCV REQUIRED )
find_package( PCL 1.7 REQUIRED COMPONENTS common io visualization filters )
find_package( CGAL QUIET COMPONENTS )
if ( NOT CGAL_FOUND )
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()
endif()
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
include( CGAL_CreateSingleSourceCGALProgram )
find_package( Boost REQUIRED )
if ( NOT Boost_FOUND )
message(STATUS "This project requires the Boost library, and will not be compiled.")
return()
endif()
SET(CMAKE_BUILD_TYPE "Debug")
SET(LIBRARY_OUTPUT_PATH "./lib")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations")
file(GLOB SOURCE_FILES ./*.cpp)
ADD_EXECUTABLE(Main ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(Main ${OpenCV_LIBS} ${PCL_LIBRARIES} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} -lCGAL -lm )
install (TARGETS Main DESTINATION ~/bin)
A quick fix: In the file include/CGAL/Surface_mesh_parameterization/Error_code.h write inline in front of const char* get_error_message(int error_code).
The fix is in this pull request, that is now merged in CGAL-4.12.

cmake on windows. Link libraries in folder

Disclaimer: I'm new to cmake so i have no idea what I'm doing.
All guides and tutorials i find seem to think I'm running a 20 man team that needs to work together.
All I'm trying to do is put all my libraries in an include folder and lib folder.
In visual studio and code::blocks i just set up the linker in the IDE, but cmake is a little hard for me to wrap my head around.
I've set include and link directories with
include_directories(${PROJECT_SOURCE_DIR}/include)
link_directories(${PROJECT_SOURCE_DIR}/lib)
Then i try to
target_link_libraries(${PROJECT_NAME} jsoncpp)
This however produces undefined references. Is there a simple way to add and link libraries without me having to google and add a cmake module for each one?
Edit:
attempts:
target_link_libraries(${PROJECT_NAME} libjsoncpp.a)
error: undefined reference
target_link_libraries(${PROJECT_NAME} libjsoncpp)
error: cannot find -llibjsoncpp
target_link_libraries(${PROJECT_NAME} jsoncpp)
error: undefined reference
target_link_libraries(${PROJECT_NAME} C:/Repos/prosjekt-bad-racoon/lib/libjsoncpp.a)
error: undefined reference
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/lib/libjsoncpp.a)
error: undefined reference
Edit:
Full cmake file
cmake_minimum_required(VERSION 3.8)
project(prosjekt_bad_racoon)
set(CMAKE_CXX_STANDARD 11)
include_directories(${PROJECT_SOURCE_DIR}/include)
link_directories(${PROJECT_SOURCE_DIR}/lib)
set(SOURCE_FILES main.cpp Core.cpp Core.h Collider.cpp Collider.h Player.cpp Player.h Texture.cpp Texture.h AudioController.cpp AudioController.h)
add_executable(prosjekt_bad_racoon ${SOURCE_FILES})
set(EXECUTABLE_NAME ${PROJECT_NAME})
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
target_link_libraries(${PROJECT_NAME} libjsoncpp.a)
find_package(SFML 2 REQUIRED system window graphics network audio)
if(SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES})
link_directories("${PROJECT_SOURCE_DIR}")
endif()
"C:\Program Files\JetBrains\CLion 2017.2.2\bin\cmake\bin\cmake.exe" --build C:\Repos\prosjekt-bad-racoon\cmake-build-debug --target prosjekt_bad_racoon -- -j 2
[ 14%] Linking CXX executable prosjekt_bad_racoon.exe
CMakeFiles\prosjekt_bad_racoon.dir/objects.a(Core.cpp.obj): In function `ZN4CoreC2Ev':
C:/Repos/prosjekt-bad-racoon/Core.cpp:3: undefined reference to `Json::Value::Value(char const*)'
CMakeFiles\prosjekt_bad_racoon.dir/objects.a(Core.cpp.obj): In function `ZN4CoreD2Ev':
C:/Repos/prosjekt-bad-racoon/Core.cpp:8: undefined reference to `Json::Value::~Value()'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\prosjekt_bad_racoon.dir\build.make:236: recipe for target 'prosjekt_bad_racoon.exe' failed
mingw32-make.exe[3]: *** [prosjekt_bad_racoon.exe] Error 1
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/prosjekt_bad_racoon.dir/all' failed
mingw32-make.exe[2]: *** [CMakeFiles/prosjekt_bad_racoon.dir/all] Error 2
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/prosjekt_bad_racoon.dir/rule' failed
mingw32-make.exe[1]: *** [CMakeFiles/prosjekt_bad_racoon.dir/rule] Error 2
Makefile:117: recipe for target 'prosjekt_bad_racoon' failed
mingw32-make.exe: *** [prosjekt_bad_racoon] Error 2

CMake-generated Makefile does not contain target

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

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.