Linking to a .so library in cmake - gcc

I have a libmosquittopp.so in /usr/lib folder.
The mosquittopp.h is inside /usr/include folder.
I like to link to my project to that lib.
So my CMakeLists.txt file is
cmake_minimum_required(VERSION 2.6)
PROJECT(MosquittoTest)
# The version number.
set (VERSION_MAJOR 1)
set (VERSION_MINOR 0)
include_directories("${PROJECT_BINARY_DIR}")
# Linked libariries
#For MQTT
#location of raspicam's cmake file is /usr/src/raspicam-0.1.3/build
link_directories(/usr/lib)
target_link_libraries (MosquittoTest mosquittopp)
ADD_EXECUTABLE(MosquittoTest MosquittoTest.cpp)
# add the install targets
install (TARGETS MosquittoTest DESTINATION bin)
install (FILES MosquittoInterface.h DESTINATION include)
But when I configure in ccmake GUI, I have error as
Cannot specify link ibraries for target MosquittoTest which is not built by this project.
What is wrong with my cmake?

I made mistake as these two lines need to be swapped.
target_link_libraries (MosquittoTest mosquittopp)
ADD_EXECUTABLE(MosquittoTest MosquittoTest.cpp)

Related

How to install dependent libraries with CMake?

I want to install all dependent libraries.
To do that I do
install(FILES "path/external.dll" DESTINATION lib)
However, I have already configured the path(and the lib) with target_link_libraries:
target_link_libraries(${PROJECT_NAME} PUBLIC "path/external.dll")
So, I think that I might not need again telling install FILES
I would be able to do this with install TARGETS, would not I?
However,
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin LIBRARY DESTINATION lib)
does not install dependent libraries.
How could I do that without repeating it?
CMake 3.21 added an argument to install(TARGETS) for this: RUNTIME_DEPENDENCIES. Try this:
include(GNUInstallDirs)
install(
TARGETS my_target
RUNTIME_DEPENDENCIES
[DIRECTORIES ...]
)
Where DIRECTORIES marks the beginning of an optional list of search paths. Also note that including GNUInstallDirs sets up the default destinations correctly.
See the docs: https://cmake.org/cmake/help/latest/command/install.html#targets

cmake ClanLib i can't compile project

cmake_minimum_required(VERSION 3.1)
project(ClanLib)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
SET(ClanLib_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${ClanLib_INCLUDE_DIRS})
FIND_PACKAGE(ClanLib REQUIRED)
set(SOURCE_FILES main.cpp)
add_executable(ClanLib ${SOURCE_FILES} main.cpp)
TARGET_LINK_LIBRARIES(ClanLib ${ClanLib_LIBRARY})
and cmake give error:
Error:By not providing "FindClanLib.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "ClanLib", but CMake did not find one.
Could not find a package configuration file provided by "ClanLib" with any of the following names:
ClanLibConfig.cmake clanlib-config.cmake
Add the installation prefix of "ClanLib" to CMAKE_PREFIX_PATH or set "ClanLib_DIR" to a directory containing one of the above files. If "ClanLib" provides a separate development package or SDK, be sure it has been installed.
There is no FindClanLib.cmake provided by ClanLib project or CMake, so find_package will not work in your case.
For Linux you can use pkg-config facility from CMake.
Here the example for ClanLib usage on Linux.

CMake install is not installing libraries on Windows

For some reason, the below CMake file fails to install the project libraries. It creates the directory in the right location, and it even recursively installs the headers... But it fails to install the library. How can this be fixed?
cmake_minimum_required(VERSION 2.8)
project(MyLib)
include_directories(include)
add_library(MyLib SHARED source/stuff.cpp)
if(CMAKE_SYSTEM MATCHES "Windows")
target_link_libraries(MyLib DbgHelp ws2_32 iphlpapi)
set(CMAKE_INSTALL_PREFIX "../../devel_artifacts")
endif(CMAKE_SYSTEM MATCHES "Windows")
install(TARGETS MyLib LIBRARY DESTINATION "lib"
ARCHIVE DESTINATION "lib"
COMPONENT library)
install(DIRECTORY include/${PROJECT_NAME} DESTINATION include)
You're just missing the RUNTIME DESTINATION argument in the install(TARGETS...) command.
CMake treats shared libraries as runtime objects on "DLL platforms" like Windows. If you change your command to:
install(TARGETS MyLib LIBRARY DESTINATION "lib"
ARCHIVE DESTINATION "lib"
RUNTIME DESTINATION "bin"
COMPONENT library)
then you should find that MyLib.dll ends up in "devel_artifacts/bin".

Add libraries Qt and LuaJIT / Lua51 with CMake

I am trying to use CMake with Qt and LuaJIT that will run on Visual Studio 2012. I managed somehow to run Qt, but i don't know how to add LuaJIT library to project. I am using source of LuaJIT cloned from http://luajit.org/git/luajit-2.0.git, which is build by running .bat file.
I dont care that LuaJIT will be build by CMake, i just need to link library and add headers to project.
I removed lib folder from my project... Is not worth troubles to have dependancies coupled with project whitout cmake file :D
My project hierarchy is:
+lib
-luajit-2.0
+src
-my sources
+ui
-ui files
-CMakeLists.txt
And CMakeLists.txt file looks like this:
cmake_minimum_required(VERSION 2.8.12)
set(PROJECT "Grapedit")
project(${PROJECT})
# Qt Stuff
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt5Widgets REQUIRED)
set(SOURCE_FILES
src/main.cpp
src/mainwindow.h
src/mainwindow.cpp
)
set(UI_FILES
ui/mainwindow.ui
)
source_group("UI Files" FILES ${UI_FILES})
qt5_wrap_ui(UI_HEADERS ${UI_FILES})
source_group("Generated UI Headers" FILES ${UI_HEADERS})
add_executable(${PROJECT} ${SOURCE_FILES} ${UI_HEADERS} ${UI_FILES})
qt5_use_modules(${PROJECT} Widgets)
My solution
So it is finally working and I made couple of newbie mistakes... :)
I will write them down for others:
didn't know what is find module... This will search environment and set up locations of libraries or flag that it didn't find them. Since LuaJIT is compatible with Lua51 you can use find_package(Lua51).
Your libraries must be some way visible to CMake. On Windows simplest way is to add them to PATH variable. Or you can add path of your libraries to CMake variable CMAKE_PREFIX_PATH. Open find module, for example FindLua51.cmake and you will see how must be your library organized. On windows I've must installed LuaJIT manualy - created LuaJIT folder and I've put *.h files to include subfolder, *.dll to bin subfolder and *.lib to lib subfolder. Then add bin folder to PATH and set LUA_DIR to LuaJIT folder.
use include_directories on include folder
then you must link libraries target_link_libraries, but after add_executable!
My CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8.12)
# Declare project variables...
set (PROJECT "Grapedit")
set (
SOURCE_FILES
src/main.cpp
src/mainwindow.h
src/mainwindow.cpp
)
set(UI_FILES
ui/mainwindow.ui
)
# Set project name
project(${PROJECT})
# Include Lua directories
include_directories(${LUA_INCLUDE_DIR})
# Qt Stuff
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
# Find packages...
# Will find also LuaJIT, but must be named same as Lua51 and installed into directories
find_package(Lua51)
# Find Qt modules, every module separately
find_package(Qt5Widgets REQUIRED)
# Create nice groups in IDEs
source_group("UI Files" FILES ${UI_FILES})
source_group("Generated UI Headers" FILES ${UI_HEADERS})
# Use Qt UI files
qt5_wrap_ui(UI_HEADERS ${UI_FILES})
# Create executable
add_executable (
${PROJECT}
${SOURCE_FILES}
${UI_HEADERS}
${UI_FILES}
)
# Link libraries...
# Must be after executable is created!
# Link Qt modules
qt5_use_modules (
${PROJECT}
Widgets
)
# Link Lua
target_link_libraries(${PROJECT} ${LUA_LIBRARIES})
# Will not show new windows prompt when running program
if (MSVC)
set_target_properties(${PROJECT} PROPERTIES
WIN32_EXECUTABLE YES
LINK_FLAGS "/ENTRY:mainCRTStartup"
)
endif ()
You are missing the actual linkage which you can amend with the following statement:
target_link_libraries(${PROJECT} luajit-5.1)
For sure, it would be even better if this lua jit could have a cmake find module, or config/version file depending on its exact build system.
You could grab the find module from here:
https://github.com/brimworks/lua-zlib/blob/master/cmake/Modules/FindLuaJIT.cmake
Then you could link against it as follows:
target_link_libraries(${PROJECT} ${LUA_LIBRARIES})
You can see that it would become more dynamic this way rather than hard-coding the exact name. The details for figuring out that would be left with the find module.
Note that you would probably need to use the corresponding variables for the header inclusion then as follows:
include_directories(${LUA_INCLUDE_DIR})
This will take care of automatically finding the include directory, respectively, without you hard-coding it.
You would also need to add the following line into your CMakeLists.txt:
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
and you need to place the downloaded find module into a "cmake" subfolder.
Please refer to the following page for further details about this topic in general:
CMake:How To Find Libraries

install(TARGETS ...) and add_subdirectory

Is it possible to use install(TARGETS ...) with targets that are defined in directories added with add_subdirectory?
My use case is, that I want to build e.gg an rpm for gtest. the gtest project happens to have a CMakeLists.txt without any install statements. I want to build the package without adding those statements to the CMakeLists.txt of gtest.
I have this resulting directory structure:
+ gtest-1.5.0/...
+ CMakeLists.txt
The CMakeLists of gtest-1.5.0 defines libraries like this:
cxx_static_library(gtest "${cxx_strict}" src/gtest-all.cc)
cxx_static_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
target_link_libraries(gtest_main gtest)
now i want to add something like this to my CMakeLists.txt:
add_subdirectory(gtest-1.5.0)
install(TARGETS gtest gtest_main ARCHIVE DESTINATION lib)
but cmake correctly states:
CMake Error at CMakeLists.txt:10 (install):
install TARGETS given target "gtest" which does not exist in this
directory.
Is there a way to do this without patching gtest-1.5.0?
You could try using file install rather than install targets. The downside is that you will have to handle shared and static builds.
install(FILES gtest-1.5.0/gtest_main.so DESTINATION lib)

Resources