How to specify where to find a shared library using CMake? [duplicate] - c++

This question already has answers here:
CMake link to external library
(6 answers)
Closed 5 years ago.
I am trying to link to a shared library using CMake. I understand that this can bee achieved using the target_link_libraries() command. I have been able to get this working but not quite in the way that I would like.
Using the below CMakeLists.txt, I've been able to link to the shared library.
cmake_minimum_required(VERSION 3.7)
project(DylibTest)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(DylibTest ${SOURCE_FILES})
target_link_libraries(DylibTest
${CMAKE_SOURCE_DIR}/Resources/libDynamicTest.dylib)
This seems to tell the linker to look in the directory that the project is located in. This is fine for development, but how would I distribute this project? End-users will clearly not have this same folder.
I've tried to pass in a relative path like so:
cmake_minimum_required(VERSION 3.7)
project(DylibTest)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(DylibTest ${SOURCE_FILES})
target_link_libraries(DylibTest /Resources/libDynamicTest.dylib)
When doing this, I get the following error:
No rule to make target `/Resources/libDynamicTest.dylib', needed by `DylibTest'. Stop.
I've looked at the documentation for target_link_directories() but it has not been helpful. I've also looked at numerous other questions here.
In case it's not clear, my intention is to distribute the executable with a folder named "Resources" that contains the shared library. How should my CMakeLists.txt file look in order to do this?
EDIT: In response to this question being marked as a possible duplicated of this question, I do concede that that question is basically asking the same thing, the answers there do not work for me.
Here's how my CMakeLists.txt looks after trying a accepted answer on the other question:
cmake_minimum_required(VERSION 3.7)
project(DylibTest)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(DylibTest ${SOURCE_FILES})
link_directories(${CMAKE_BINARY_DIR}/Resources)
target_link_libraries(DylibTest DynamicTest)
This unfortunately does not work an results in an error stating that the library could not be found.

Have a look at https://cmake.org/cmake/help/v3.0/command/find_library.html.
You can specify one or more alternative search folder for cmake to look for the library. It also looks in the default library folder for your OS as well.
find_library(YOURLIB
NAMES your // without the lib
PATHS ${CUSTOM_LIB_PATH})
You can then link the library with
target_link_library(targetname ${YOURLIB})

You might be looking for Creating packages with CPack? This lets you describe how your project shall be packaged into a setup routine and what the file layout after installing looks like.

Related

What's the best practice to import external boost in a c++ cmake project?

I'd like to import external boost in a c++ cmake project.
I did several tries and finally got the following CMakeLists.txt works:
cmake_minimum_required(VERSION 3.14)
project(my_project
VERSION 0.0.1
LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 11)
include(FetchContent)
FetchContent_Declare(
boost
URL https://boostorg.jfrog.io/artifactory/main/release/1.78.0/source/boost_1_78_0.tar.bz2
)
FetchContent_MakeAvailable(boost)
set(Boost_ROOT "${CMAKE_BINARY_DIR}/_deps/boost-src")
set(BOOST_INCLUDEDIR ${Boost_ROOT})
find_package(Boost 1.78)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(
boost_test
tests/boost_test.cpp)
However, I feel a little uncomfortable because set(Boost_ROOT "${CMAKE_BINARY_DIR}/_deps/boost-src") looks hacky -- it has a strong assumption that the fetched content will be stored in _deps folder, which I rather want to put it in a dedicated folder like 3rd_party or external as typical C++ project layout conventions.
I found there're 2 ways for doing that:
Use FetchContent_Declare to download the project. However, I don't know how to execute extra build commands to compile non-header-only libraries.
Use ExternalProject_Add to download and compile the boost project. It looks like an old-fashing way, besides, I don't know how to add boost as part of dependencies to top-level CMakeLists.txt in this way.
The way I adopted is the former one, but I wonder if it's the correct way to include external boost (not system-default installed one) as part of a C++ project, or is there a best practice for doing this?
Any comments, suggestions, answers are welcome. Thanks.
The best way to use Boost in a CMake project is like this:
cmake_minimum_required(VERSION 3.25)
project(boost-example)
find_package(Boost REQUIRED)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE Boost::headers)
target_compile_features(myapp PRIVATE cxx_std_11)
Boost::headers is the library to link to for all of the Boost header-only components. If you need a component that includes a real library, then link to Boost::<component>, too, and be sure to name <component> after the REQUIRED argument to find_package.
Don't mess with FetchContent. Your users will know how to get the necessary dependencies. You can provide a vcpkg.json file or a conanfile.txt to make it easier to use Vcpkg and/or Conan, respectively.

C++ external libraries issue [duplicate]

This question already has answers here:
CMake link to external library
(6 answers)
Closed 2 years ago.
I have installed an external library named metis which resides at "/usr/local/opt/" in my system and I want to link this library to my existing make project, which seems to be difficult. I have tried a few reference links here on stackoverflow but they don't seem to work.
My CMakeLists.txt looks like this:
project(Multi)
cmake_minimum_required (VERSION 2.6)
find_package(CGAL QUIET COMPONENTS Core )
include( ${CGAL_USE_FILE} )
include_directories (BEFORE "/include")
include_directories (BEFORE "/dt")
find_package(MPI)
include_directories(SYSTEM ${MPI_INCLUDE_PATH})
SET(CMAKE_C_COMPILER mpicc)
SET(CMAKE_CXX_COMPILER mpicxx)
SET(MPIEXEC_MAX_NUMPROCS "4" CACHE STRING "Maximum number of processors available to run MPI applications.")
find_package(METIS)
include_directories("/usr/local/opt/metis/include")
add_subdirectory("/usr/local/opt/metis/include/bin")
add_executable(example example.cpp)
I have tried to add the location of the library by using add_subdirectory and include_directories tags but they don't seem to work.
Any help on this will be appreciated.
find_package() searches for the library in a set of predefined directores, and /usr/local/opt is very likely not among those. In this case, since you already know where your library is located, you can tell find_package() where to look for it:
find_package(METIS REQUIRED PATHS /usr/local/opt/metis)
Also, add_subdirectory() works only if the specified directory contains a CMakeLists.txt. You need this only if you want to build the library metis as part of your build process, and if that directory is the root of the metis library, and it used CMake for building too. If you only have the header files and pre-build library files, then you do not need this.

Boost Installation in CLion

I am a complete beginner in C++ programming and have been advised to use CLion. I am trying to get the Boost package to work.
I found many posts and tutorials online, however they all skip the basics not known to someone who is not a programmer. Namely, there is no explanation of how to get from the moment you open a new project to using some function from the Boost package?
This is what I found to be lacking from previous answers:
Here we are advised to use live incboost live template, however there is no explanation on where to find it or how to use it.
Here seems like a clear tutorial, however it is aimed at Visual Studio, not CLion.
Here I am not sure what each of those files are and how to adjust them to match my case.
I have downloaded boost_1_70_0 from https://www.boost.org/users/download/ and it is now unzipped and saved in C:\...\boost_1_70_0.
Could someone please explain really simply how to get from a blank project to being able to use functions stored in boost?
Considering you are using CLion and it supports only CMake at this time and you have installed BOOST library in the default directory, then your CMakeLists.txt file should look like this. I have used it in linux operating system but it should be able in Windows too.
cmake_minimum_required(VERSION 3.13)
project(LaserCV)
set(CMAKE_CXX_STANDARD 17)
#local
file(GLOB SOURCES
*.hpp
*.cpp
)
add_executable(LaserCV ${SOURCE_FILES} ${SOURCES})
#add_executable(LaserCV main.cpp)
SET(CMAKE_CXX_FLAGS -pthread)
#boost
find_package(Boost REQUIRED)
target_link_libraries(LaserCV ${Boost_LIBRARIES})
include_directories(${Boost_INCLUDE_DIR})
Then simply include a header file for your wanted boost function, for example:
#include <boost/random.hpp>

How to properly link Graphviz in a c++ application on Ubuntu

I am having problems compiling simple example code taken from the official website here https://graphviz.gitlab.io/_pages/dot.demo/demo.c .The problem is undefined reference to Graphviz functions. I know there is a related question asked here Qt Creator cannot resolve gvContext on Ubuntu, but it didn't help.
I have included libgvc libcgraph libcdt in my CMakeLists.txt and that did't help. I have made sure that these packages are present on my machine.
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(name)
set(CMAKE_CXX_STANDARD 14)
add_executable(name main.cpp)
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(gvc REQUIRED libgvc libcgraph libcdt)
LINK_DIRECTORIES(${gvc_LIBRARY_DIRS})
INCLUDE_DIRECTORIES(${gvc_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${gvc_LIBRARIES})
Please if someone linked the library or knows how to link correctly, let me know.
Did you install the libgraphviz-dev package? That contains the libgvc pkg-config file your CMakeLists.txt needs.

How to configure libXML with CMake?

I have learned the basics of C++ programming and thought of ways how I could proceed, in order to practise. One thing that caught my interest was Web Scraping. Since I only knew BeautifulSoup, I searched for an alternative for C++ and found libXML for C++, however I'm trying to install it but don't seem to get it to work, since I barely have an idea on how to configure a CMake file. I'm using CLion as an IDE and Windows as my operating system, if it matters. My project folder is
C:\Users\Laurenz\Documents\Programming\untitled10
and the place where I've put the libXML library is
C:\Users\Laurenz\Documents\Programming\untitled10\libXML
however, I think the "main" directory is the one below (since it contains most of the Source files), but I'm not sure which of both I need to include.
C:\Users\Laurenz\Documents\Programming\untitled10\libXML\libxml++
I've searched around in the internet and found dozens of methods on how people include libraries, so I'm not sure which I need to use. What I currently have:
cmake_minimum_required(VERSION 3.6)
project(untitled10)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(untitled10 ${SOURCE_FILES})
set(CMAKE_PREFIX_PATH "C:\\Users\\Laurenz\\Documents\\Programming\\untitled10\\libXML\\libxml++")
find_package(LibXML++ REQUIRED)
include_directories(${LibXML++_INCLUDE_DIRS})
set(LIBS ${LIBS} ${LibXML++_LIBRARIES})
target_link_libraries(untitled10 ${LIBS})
However, I get the following error message:
Error:By not providing "FindLibXML++.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "LibXML++", but CMake did not find one.
Could not find a package configuration file provided by "LibXML++" with any of the following names:
LibXML++Config.cmake libxml++-config.cmake
Add the installation prefix of "LibXML++" to CMAKE_PREFIX_PATH or set "LibXML++_DIR" to a directory containing one of the above files. If "LibXML++" provides a separate development package or SDK, be sure it has been installed.
Could someone tell me how to properly configure LibXML? And maybe someone knows some resources where I can learn how CMake files work, because it confuses me a bit.
Thanks!