Include external Library cmake - c++

I want to use the SQLAPI library, i have copied all files in the include directory to usr/local/include/SQLAPI and all files from the lib directory to usr/local/lib. The lib files are named libsqlapi.a /libsqlapi.so and libsqlapiu.a /libsqlapiu.so .
My cmakeLists.txt looks like this:
project(gsl_test)
cmake_minimum_required(VERSION 2.8)
SET(CMAKE_CXX_FLAGS "-std=c++0x")
aux_source_directory(. SRC_LIST)
include_directories(usr/local/include)
link_directories(usr/local/lib)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} libsqlapi)
I get the build/linker error: cannot find -llibsqlapi.
I did also try target_link_libraries(${PROJECT_NAME} sqlapi), but it gives me additional "skipping incompatible //usr/local/lib/libsqlapi.so"
(and the same for .a) with cannot find -lsqlapi

Ok, i'll change my edit to an answer:
The reason linker complained was the fact that you specified the library in the wrong manner. lib is just prefix - if you use target_link_libraries you use the rest of library name. Changing to
target_link_libraries(${PROJECT_NAME} sqlapi)
solved that issue. The error you receive now
skipping incompatible //usr/local/lib/libsqlapi.so
Is most probably caused by the fact that you have copied all the files from some pre-build package and it's not compatible with your system. You need to recompile the library on your own.

Related

CMake is not using correct paths when looking for lib files

I recently installed vcpkg on my windows system and the cmake (and cmake tools) extension for vscode, because I wanted to use a json file for my c++ project. I had put vcpkg in a random location just to mess around with it and learn how it works. However, when I moved it to another location as its final spot, CMake got confused and couldn't find lib files for jsoncpp.
Here's the error:
Unable to open 'json_value.cpp': Unable to read file 'c:\path\to\old\location\vcpkg\buildtrees\jsoncpp\src\3918c327b1-034a82149a.clean\src\lib_json\json_value.cpp' (Error: Unable to resolve non-existing file 'c:\path\to\old\location\vcpkg\buildtrees\jsoncpp\src\3918c327b1-034a82149a.clean\src\lib_json\json_value.cpp').
I had moved vcpkg from C:\path\to\old\location\vcpkg to C:\vcpkg
And here's my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.0.0)
project(myProgram VERSION 0.1.0)
include(CTest)
enable_testing()
add_executable(myProgram main.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
# set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
set(CMAKE_BUILD_TYPE debug)
# set_target_properties(${PROJECT_NAME}
# PROPERTIES
# RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR})
include(CPack)
include_directories(C:/vcpkg/installed/x64-windows/include)
link_directories(C:/vcpkg/installed/x64-windows/lib)
find_package(jsoncpp CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE jsoncpp_lib jsoncpp_object)
I have already tried updating the CMAKE_TOOLCHAIN_FILE property in settings.json, deleting cmake's cache, resetting the extension, and reinstalling jsoncpp, vcpkg and the cmake extensions fresh (I had made sure that their files were deleted).
I had to take out the find package function. The find package function made cmake expect the source code to be in the buildtrees folder, which in this case isn't (I think it was at some point, but I don't know why it wont come back). Just by using target_link_libraries(${PROJECT_NAME} jsoncpp), as well as the include/link directories statements gave cmake everything it needed to include the library. One thing I still don't understand however is why cmake was looking in the old location for that bit of source code.

(C++17; Boost) CMake unable to find the requested Boost libraries

I am new to C++ and want to include the boost library (specifically the filesystem part which needs to be built) in my project. I tried many solutions from other stackoverflow users but they didn't help me at all. I am using CLion with CMake.
The main.cpp is calling the other .cpp files inside the modules/ folder.
The file structure:
ProjectName
>boost
>lots of folders and .hpp files
>cmake-build-debug
>modules
encryption.cpp
encryption.h
output.cpp
output.h
CMakeLists.txt
main.cpp
The boost folder doesn't contain the entirety of boost when you download and extract it. I dragged the boost folder inside of boost_1_72_0 in my project (just so you know that there's no libs folder, etc. inside)
The CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(ProjectName)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc")
set(SOURCE_FILES
main.cpp
modules/encryption.cpp modules/encryption.h modules/output.cpp modules/output.h
)
set(Boost_ARCHITECTURE -x64)
set(BOOST_ROOT boost/)
set(Boost_INCLUDE_DIRS boost/filesystem)
find_package(Boost COMPONENTS system filesystem REQUIRED)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif()
add_executable(ProjectName ${SOURCE_FILES})
target_link_libraries(ProjectName ${Boost_LIBRARIES})
output.cpp
// some includes //
#define BOOST_FILESYSTEM_NO_DEPRECATED
#include "../boost/filesystem.hpp"
// some code //
The Error message:
CMake Error at C:/Program Files/JetBrains/CLion 2019.1.4/bin/cmake/win/share/cmake-3.14/Modules/FindBoost.cmake:2147 (message):
Unable to find the requested Boost libraries.
Unable to find the Boost header files. Please set BOOST_ROOT to the root
directory containing Boost or BOOST_INCLUDEDIR to the directory containing
Boost's headers.
Call Stack (most recent call first):
CMakeLists.txt:15 (find_package)
-- Configuring incomplete, errors occurred!
See also "C:/Users/username/Desktop/C++/ProjectName/cmake-build-debug/CMakeFiles/CMakeOutput.log".
mingw32-make.exe: *** [cmake_check_build_system] Error 1
Makefile:235: recipe for target 'cmake_check_build_system' failed
I know that it's basically telling me what I have to do but I don't know what's exactly meant by the "root directory" of boost, by the directory "containing Boost's headers" and how to put everything together.
Many thanks in advance!
I dragged the boost folder inside of boost_1_72_0 in my project
Looks like you just copied boost source into your project dir.
You have to compile boost since you need filesystem. Or you can get boost from:
vcpkg - it's the easiest way for you. I am highly recommended this way.
Sourceforge.
Conan
I don't know what's exactly meant by the "root directory"...
Since you are using boost by calling find_package(Boost) - CMake uses FindBoost module. It will try to find your boost installation inside system PATH variable or in some other "standard" places. Your boost "installation" is not common, so you have to specify where boost is with BOOST_ROOT variable. set(BOOST_ROOT boost/) is incorrect way to do this. You have to specify absolute path like set(BOOST_ROOT "C:/lib/boost/boost17.2")
or relative to current CMakeList.txt - set(BOOST_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/boost}.
With right installed boost all you have to do is:
find_package(Boost REQUIRED [COMPONENTS <libs>...])
target_link_libraries(main PRIVATE ${Boost_LIBRARIES})
target_include_directories(main PRIVATE ${Boost_INCLUDE_DIRS})
Usually, you don't need to set Boost_ARCHITECTURE and Boost_INCLUDE_DIRS CMake does it for you.
When you use find_package with REQUIRED option you don't need to check whether the library found or not since CMake raises an error when a library isn't found.
BOOST_ROOT is a directory when boost installed or unpacked.
BOOST_INCLUDEDIR is a directory with boost headers (usually it's BOOST_ROOT/boost). So try to set the full path to your boost_1_72_0 directory to BOOST_ROOT CMake variable.
Also, I had a problem with COMPONENTS option. Try to remove it if errors remain.

proper way to write a CMakeLists referencing HDF5 in Windows

I've already downloaded an built HDF5 under Windows using CMake, I also generated an installer to install it under Program Files.
Below the CMakeLists.txt I wrote to be able to use HDF5 in a program I already wrote under Linux :
cmake_minimum_required(VERSION 2.8)
project(Hdf5DataFeed)
add_definitions(-DWINDOWS)
find_package(HDF5)
FIND_LIBRARY(HDF5_HL_LIBRARY hdf5_hl)
FIND_LIBRARY(ZLIB zlib)
find_library(ZMQ_LIB zmq)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
include_directories(${ZMQ_LIB_INCLUDE})
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} ${ZLIB} "C:/Program Files/HDF_Group/HDF5/1.10.1/lib/libszip.lib" ${VTK_LIBRARIES} ${ZMQ_LIB} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets)
target_include_directories(${PROJECT_NAME} PRIVATE ${HDF5_INCLUDE_DIRS})
As you can see above, to link HDF5 under Visual Studio, I needed Zlib, Szip (that I had to enter an absolute path to it, I don't like that), HDF5 library and the HDF5 High Level (Lite) library.
These libraries are located under C:\Program Files\HDF_Group\HDF5\1.10.1\lib :
libhdf5.lib <============
libhdf5.settings
libhdf5_cpp.lib
libhdf5_hl.lib <=====
libhdf5_hl_cpp.lib
libhdf5_tools.lib
libszip.lib <=== ????
libzlib.lib <====
I use CMake-Gui to inform CMake of the libraries path (except for Szip, I don't know why CMake doesn't know about it, and why I don't have the possibility to just feed CMake the library directory instead of indicating the path of few of them).
I want to use CMake-GUI to inform CMake of Szip library path, but this last doesn't create an entry of it, I only have these entries related to HDF5 :
I'm having troubles with HDF5 also under Ubuntu (see this question : hdf5.h no such file or directory under Ubuntu and CMake).
For now, it's only under CentOS 7 that I didn't encounter any issues with HDF5.
If someone can give me/us a final solution that works both on Windows and Ubuntu that would be great !
Does this solution work for you?
cmake_minimum_required(VERSION 2.8)
project(Hdf5DataFeed)
# necessary?
add_definitions(-DWINDOWS)
find_package(HDF5 REQUIRED COMPONENTS C CXX HL)
find_package(ZLIB REQUIRED)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
find_library(ZMQ_LIB zmq)
include_directories(${ZMQ_LIB_INCLUDE} ${HDF5_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS})
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
target_link_libraries(${PROJECT_NAME} ${HDF5_LIBRARIES}
${HDF5_HL_LIBRARIES} ${ZLIB_LIBRARIES} ${VTK_LIBRARIES}
Qt5::Core Qt5::Gui Qt5::Widgets ${ZMQ_LIB})
Recommendation 1: Surely, there is a way to find Qt5 via find_package, i.e.,
find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
and then add the correct variables to include_directories and target_link_libraries. Not sure whether such a possibility exists for the zmq library, though.
Recommendation 2: I think the call the aux_source_directory should be avoided in most cases. Create an explicit list of your source files instead.
For libszip, adding a find_library is better than putting an absolute link to it. For ZLib, it is preferable to use find_library as find_package will require you to feed CMake with an include directory which is not required for HDF5. Finally, it is preferable to use find_package for ZMQ, otherwise, we need to add manually the entry "ZMQ_LIB_INCLUDE".

My project can find one library header, but not another one

I have two C++ libraries, which I am using on Ubuntu. One of them, let's call it foo, I installed through apt-get, e.g. sudo apt-get install libfoo-dev. The other, let's call it bar, I installed by downloading the source files, and running make install. After these installations, I then have header files from foo in locations such as /usr/include/foo/foo.h, and header files from bar in locations such as /usr/local/include/bar/bar.h. From my knowledge, foo is a dependency of bar.
I then created my own C++ project, and included the line #include "bar/bar.h". But when compiling my project, I get an error saying error: foo.h: No such file or directory. If I click on the error in my debugger, it opens the file bar.h, and highlights the line #include <foo.h>. So, my project is able to find bar.h, but not foo.h. I do not mention either foo or bar in my CMakeLists.txt file.
So my questions are:
How does my project know how to find bar.h, when I have not told it where to find it in CMakeLists.txt?
What do I need to do to get my project to find foo.h and compile properly?
Thank you!
Edit: Here is my CMakeLists.txt file (the foo and bar libraries are none of the ones mentioned here):
cmake_minimum_required(VERSION 2.8.1)
set(CMAKE_CXX_FLAGS "-std=c++11 -O3")
project(Grasping_Simulator)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(GLUT REQUIRED)
find_package(Eigen3 REQUIRED)
find_package(Boost REQUIRED)
find_package(OpenCV REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIR} ${GLUT_INCLUDE_DIR} ${EIGEN3_INCLUDE_DIR} ${BOOST_INCLUDE_DIRS} ${OPENCV_INCLUDE_DIRS})
file(GLOB SRCS *.cpp *.h)
add_executable(${PROJECT_NAME} ${SRCS})
target_link_libraries(${PROJECT_NAME} ${GLEW_LIBRARY} ${GLUT_LIBRARY} ${OpenCV_LIBS} pthread GL boost_system)
You need to add the option -I/usr/include/foo/ to your compilation command.
By default, locations such as /usr/include/ and /usr/local/include are already in the include search path. However, your library bar does something naughty by using #include <foo.h>. Really, it should be using things like #include <foo/foo.h> (by the way if you can make this change that would be cleaner). That would allow the compiler to search all its include paths, including the path /usr/include/, and try appending /foo/foo.h - which would succeed. As it stands, there is nothing in the default include path which would work merely by appending /foo.h, so it fails to find it.
EDIT: Given your CMake code above, most likely you need to append a variable that contains the value /usr/include/foo to the include_directories line to achieve the desired effect (this being the inclusion of -I/usr/include/foo/ on the compilation line).

Cannot find library with simple C++ example

I am building a C++ library called alpha in Ubuntu with cmake, which contains one source file:
cmake_minimum_required(VERSION 2.8)
project(Alpha)
add_library (alpha alpha.cpp)
This creates a file called libalpha.a, which I now want to link to. So, I copy it into the source directory of another C++ projected called beta, which also contains one source file:
cmake_minimum_required(VERSION 2.8)
project(Beta)
add_executable(beta beta.cpp)
target_link_libraries(beta alpha)
However, I get the following error:
/usr/bin/ld: cannot find -lalpha
The same thing happens if I use the line:
target_link_libraries(beta libalpha.a)
Why can beta not find the alpha library?
If you wish to build the library and the program completely separately, you have to use imported targets. When you try to link your executable against a "completely unknown" library, CMake build system automatically passes the task of locating the library to the linker, simply adding -lalpha option. When the linker encounters the option it attempts to locate libalpha.so in one of the standard library locations (i.e. /usr/lib/, /usr/local/lib etc) and expectedly fails. You can use an absolute path to the libalpha.a: target_link_libraries(beta /path/to/libalpha.a).
However if you can build things together, this greatly simplifies the task. Consider
<project>/CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
Project(Test)
add_subdirectory(alpha)
add_subdirectory(beta)
<project>/alpha/CMakeLists.txt
cmake_minimum_required(VERSION 2.8.11)
project(alpha)
set(SOURCES alpha.c)
add_library(alpha ${SOURCES})
target_include_directories(
alpha INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"
)
target_include_directories() with the complex expression within is required to automatically add libalpha include directories to all components which later are linked against libalpha.
<project>/beta/CMakeLists.txt
project(beta)
set(SOURCES beta.c)
add_executable(beta ${SOURCES})
target_link_libraries(beta alpha)
Add this line with the path to alpha-library.
link_directories( <library path> )