CMake install is not installing libraries on Windows - 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".

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

How to prevent CMake from installing .lib files

I am cross-compiling a JNI DLL on Windows using MSVC + CMake and I noticed that it is producing a .lib file on install. I am using add_library(mylibname SHARED ...) and install(TARGETS mylibname DESTINATION ${CMAKE_INSTALL_LIBDIR}) to create and install the shared library. Is there a way to prevent this file from being installed as it is not needed for JNI libraries at runtime?

Library's CMake generates DLL. Application's CMake wants LIB

My library has minimal, straightforward CMake code with the pertinent lines
add_library(MyLib <sources>)
install(
TARGETS MyLib
LIBRARY DESTINATION ${destination}/lib
RUNTIME DESTINATION ${destination}/lib
COMPONENT Libraries)
install(
FILES mylib.h
DESTINATION ${destination}/include
COMPONENT Headers)
When executed under Windows, the system generates mylib.dll in ...\build\Release, and mylib.lib and mylib.exp (what's that?) in ...\build\lib\Release. It only installs mylib.dll.
My application has minimal, straightforward CMake code to search for my library:
find_path(MyLib_INCLUDE_DIR mylib.h)
find_library(MyLib_LIBRARIES NAMES MyLib)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MyLib DEFAULT_MSG MyLib_LIBRARIES MyLib_INCLUDE_DIR)
Which works under Linux, but under Windows results in
-- Could NOT find MyLib (missing: MyLib_LIBRARIES)
From experimentation I know that this error occurs whenever there is only a .DLL file, and no associated .LIB import library.
Shall I correct MyLib to install mylib.lib? How?
Or is it possible to modify my application so that it is satisfied with mylib.dll only? How?
Research done so far
This is not about static vs dynamic linking (DLL and LIB files - what and why?, cmake link against dll/lib): I want dynamic linking; if a .LIB file is required, it has nothing to do with static linking.
This link cmake : shared library : how to get the .lib name instead of .dll name? may be pertinent, but is not explicit enough. Two other questions CMake generated VS project expecting lib instead of dll, Linking dll/lib to a cmake project seem related, but have no answer.
Command install classifies .lib file for a shared library as ARCHIVE. This is explicitly stated in the documentation:
For DLL platforms (all Windows-based systems including Cygwin), the DLL import library is treated as an ARCHIVE target.
So you need to add ARCHIVE clause to install() for install .lib file as well:
install(
TARGETS MyLib
ARCHIVE DESTINATION ${destination}/lib
LIBRARY DESTINATION ${destination}/lib
RUNTIME DESTINATION ${destination}/bin
COMPONENT Libraries)
Not also, that RUNTIME DESTINATION is usually specified as bin, the same as destination for executables. This helps the executables on Windows to locate the shared libraries (.dll).

Linking to a .so library in cmake

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)

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