Including my own shared library with cmake - c++

I have the following code in my CMakeLists.txt for finding my shared library libsieve.so
set(CPPLIB_DIR "${CMAKE_SOURCE_DIR}/../core/build")
find_library(CPPLIB_SIEVE_LIBRARY NAMES libsieve PATHS CPPLIB_DIR)
But it fails and won't find my library. I have the following directory structure:
core
build: libsieve.so
project: CMakeLists.txt
What am I doing wrong?

I don't know why cmake doesn't find the needed library but I can suggest a way to make it happen with the help cmake-gui: if the first run of "configure" fails to find the library you can point it to the needed library manually (set the full absolute path). Most of the time such solution works for me.
Also if the library was built with one tool chain (say, Intel C++) and you project is being built with another tool chain (say, clang) the failure to find the library may be due to binary incompatibility between the project and the library.
Upd. The original problem was referencing CPPLIB_DIR. It should have been:
find_library(CPPLIB_SIEVE_LIBRARY NAMES sieve PATHS ${CPPLIB_DIR})

Cmake find_library expect you to provide the library name or the library file name.
You mixed the two by adding a "lib" prefix to your library name. So you should try to replace libsieve by either sieve or libsieve.so.

Related

how to link third-part library in cmake

I'm currently work with the project that chosen the CMake as the build system.
Nonetheless, I'm not very familiar with CMake. I spent much time on including the third-party library, the result is not very prefer. Could someone provide a way to fix my scenario?
My project tree is given in following section:
|--->top-Level
|--->ThirdLib
|------>Lib1
|---------->DLL
|---------->Include
|---------->LIB
|------>Lib2
|---------->DLL
|---------->Include
|---------->LIB
|--->UseThirdLib
|----->test.h //this file will used third-part lib
it seems u need some basic cmake tutorial?
https://cmake.org/cmake/help/latest/guide/tutorial/Adding%20a%20Library.html
target_include_directories
target_link_libraries
in Top level CmakeLists.txt
include_directories(${PROJECT_SOURCE_DIR}/ThirdLib/Lib1/include)
include_directories(${PROJECT_SOURCE_DIR}/ThirdLib/Lib2/include)
target_link_directories(your_target_name ${PROJECT_SOURCE_DIR}/ThirdLib/Lib1/lib)
target_link_directories(your_target_name ${PROJECT_SOURCE_DIR}/ThirdLib/Lib2/lib)
And all .dll should be placed in the same folder as executable or env:PATH should refer to folder with .dlls

How to use cmake to check if some libraries exists before build our sources?

Usually, open source packages will have cmake to check if some headers or libraries exists or not, I wish my own project has this same functionality.
So I wish to know if cmake provides some command to check if some ".so"/".a"/".h" files exists in the current linux system or not, if not cmake will give me some hint to install them?
How does cmake support this?
Usually one would use the find_package(ABC REQUIRED) and then refer to it in your project. This will ensure that the dependent library is installed and cmake will fail if it is not.
You can find lot's of example on how this works in your cmake installation, for example C:\Program Files\CMake\share\cmake-3.13\Modules\FindZLIB.cmake will search for the zlib library by looking in the file system for normal places where this library would be installed and if it finds it will set these variables accordingly:
# ZLIB_INCLUDE_DIRS - where to find zlib.h, etc.
# ZLIB_LIBRARIES - List of libraries when using zlib.
# ZLIB_FOUND - True if zlib found.
To achieve this header files are found using the cmake command find_path, and libraries (static and shared) are found using find_library.
To search for arbitrary library you can use find_library() command. Same task for headers is accomplished by find_file(). You can also search for executables with find_program().
As #Damian said in his naswer, many libraries provide "config" files, like FindBoost.cmake. Such libraries can be found by calling find_package(Boost) command. This command would locate and load config file and set corresponding variables.
You need to provide -config.cmake files to tell other projects where your libraries and headers are. Here, you will found what are you looking for.

Build a specific Boost library using a makefile

I am trying to include, the boost::filesystem library into a project.
The project has to run on different architectures, so I don't want to link to the boost libraries installed on my ubuntu machine.
Most of boost is header only, so I would just have to include it and not worry about building it. But the filesystem library is NOT header only and I have to build the binaries for it.
Doing that would be easy, just pass in the header using the -I flag, and during the linking state, pass in the location to search for the binary using -L and specify the library using -l.
But I don't want to use the system headers and binaries.
So I am keeping a copy of the boost::filesystem headers within my project, using the bcp tool that boost provides.
I am able to do this, and I have a subdirectory lib/fs/boost/filesystem.
When I try to build a cpp file, dependent on filesystem, the compiler is able to find the headers and everything works.
But during the linking state. It cannot find the binary and the build fails.
So how do I build the boost::filesystem ?
1) I found the bootstrap.sh and b2 way to do it. I am not sure how to use it with the bcp tool though. I was building the library from the boost root.
But a disadvantage this this approach, is that I am complicating things. Before running my makefile, I will have to run bootstrap and b2 to get the binaries. It doesn't seem clean and I would like to avoid this.
2) Is there a makefile rule that I can use to build the boost::filesystem. The project is build using a makefile, and if I could specify a rule to build the filesystem, and then link the resulting binaries, it would be great.
I searched online and I couldn't find a makefile to build a boost library. Can you point me at where I could find such a makefile ?
The question is verbose, but I am just doing it to make sure I am not making any wrong assumptions.
Thanks a lot.

Embedding library and it's includes via CMake

I'm creating a very small project that depends on the following library: https://github.com/CopernicaMarketingSoftware/AMQP-CPP
I'm doing what i always do with third-party libraries: i add their git repo as a submodule, and build them along with my code:
option(COOL_LIBRARY_OPTION ON)
add_subdirectory(deps/cool-library)
include_directories(deps/cool-library/include)
target_link_libraries(${PROJECT_NAME} coollib)
This has worked perfectly for libraries like Bullet, GLFW and others. However, this AMQP library does quite an ugly hack. Their include directory is called include, but in their CMake install() command, they rename it to amqpcpp. And their main header, deps/cool-library/amqpcpp.h, is referencing all other headers using that "fake" directory.
What happens is: when CMake tries to compile my sources which depend on deps/cool-library/amqpcpp.h, it fails because it's not finding deps/cool-library/amqpcpp/*.h, only deps/cool-library/include.
Does anyone have any idea how i can fix this without having to bundle the library into my codebase?
This is not how CMake is supposed to work.
CMake usually builds an entire distributive package of a library once and then installs it to some prefix path. It is then accessible for every other build process on the system by saying "find_package()". This command finds the installed distibution, and all the libs, includes etc. automagically. Whatever weird stuff library implementers did, the resulting distros are more or less alike.
So, in this case you do a lot of unnecessary work by adding includes manually. As you see it can also be unreliable.
What you can do is:
to still have all the dependencies source distributions in submodules (usually people don't bother doing this though)
build and install each dependency package into another (.gitignored) folder within the project or outside by using their own CMakeLists.txt. Let's say with a custom build step in your CMakeLists.txt
use "find_package()" in your CMakeLists.txt when build your application
Two small addition to Drop's answer: If the library set up their install routines correctly, you can use find_package directly on the library's binary tree, skipping the install step. This is mostly useful when you make changes to both the library and the dependent project, as you don't have to run the INSTALL target everytime to make library changes available downstream.
Also, check out the ExternalProject module of CMake which is very convenient for having external dependencies being built automatically as part of your project. The general idea is that you still pull in the library's source as a submodule, but instead of using add_subdirectory to pull the source into your project, you use ExternalProject_Add to build it on its own and then just link against it from your project.

How to use external DLLs in CMake project

I've been searching over the internet but I couldn't find anything that would answer my question (or I don't know what to search for).
Anyway here's my issue:
I want to use 3rdParty libraries (.dll files) in my CMake project. Library (https://github.com/pitzer/SiftGPU) that I want to include is open source and is also available in binary which I would like to use and also uses CMake as build tool if that's relevant.
I hope I was clear enough.
First, edit your CMakeLists.txt to include your third party library. You'll need two thing: path to header files and library file to link to. For instance:
# searching for include directory
find_path(SIFTGPU_INCLUDE_DIR siftgpu.h)
# searching for library file
find_library(SIFTGPU_LIBRARY siftgpu)
if (SIFTGPU_INCLUDE_DIR AND SIFTGPU_LIBRARY)
# you may need that if further action in your CMakeLists.txt depends
# on detecting your library
set(SIFTGPU_FOUND TRUE)
# you may need that if you want to conditionally compile some parts
# of your code depending on library availability
add_definitions(-DHAVE_LIBSIFTGPU=1)
# those two, you really need
include_directories(${SIFTGPU_INCLUDE_DIR})
set(YOUR_LIBRARIES ${YOUR_LIBRARIES} ${SIFTGPU_LIBRARY})
endif ()
Next, you can do the same for other libraries and when every libraries are detected, link to the target:
target_link_libraries(yourtarget ${YOUR_LIBRARIES})
Then you can configure your project with CMake, but as it doesn't have any magic way to find your installed library, it won't find anything, but it'll create two cache variables: SIFTGPU_INCLUDE_DIR and SIFTGPU_LIBRARY.
Use the CMake GUI to have SIFTGPU_INCLUDE_DIR pointing to the directory containing the header files and SIFTGPU_LIBRARY to the .lib file of your third party library.
Repeat for every third party library, configure again and compile.