How can I make CPACK include 3rd party DLLs into the installer? - cmake

I've written a CMakeLists.txt as shown below:
cmake_minimum_required (VERSION 3.22)
project(tutorial)
set(wxWidgets_CONFIGURATION mswu)
find_package(wxWidgets REQUIRED COMPONENTS net core base)
include(${wxWidgets_USE_FILE})
add_executable(tutorial main.cpp)
target_link_libraries(tutorial ${wxWidgets_LIBRARIES})
install(TARGETS tutorial DESTINATION bin)
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "0")
set(CPACK_PACKAGE_VERSION_MINOR "1")
include(CPack)
As you might guess, this is WxWidgets application.
Look at the bottom. It includes InstallRequiredSystemLibraries and CPack.
With this cmake I have generated a NSIS Cpack installer "tutorial-0.1.1-win64.exe".
But this installer only installs the project binary and some runtime libraries. It doesn't install any WxWidgets library. So the project binary fails to run on other systems that is not installed WxWidgets libraries.
I'd like to make NSIS Cpack installer installs WxWidgets DLL libraries also.
How can I make it?
See! Those binaries are needed to be installed! But NSIS Cpack installer doesn't install wxbase315ud_vc14x_x64.dll and wxmsw315ud_core_vc14x_x64.dll
I am working on Windows 10
I don't want to statically link to the WxWidgets libraries. I'd like to make it link dynamically with shared libraries.

There exists a previous talk for the similar subject :
Including external libraries in cpack output
I tried this way and it works :
cmake_minimum_required (VERSION 3.22)
project(tutorial)
if(CMAKE_BUILD_TYPE MATCHES Release)
message("release mode")
set(wxWidgets_CONFIGURATION mswu)
else()
message("debug mode")
set(wxWidgets_CONFIGURATION mswud)
endif()
find_package(wxWidgets REQUIRED COMPONENTS net core base)
include(${wxWidgets_USE_FILE})
add_executable(tutorial main.cpp)
target_link_libraries(tutorial ${wxWidgets_LIBRARIES})
install(TARGETS tutorial DESTINATION bin)
if(CMAKE_BUILD_TYPE MATCHES Release)
install(FILES ${wxWidgets_LIB_DIR}/wxbase315u_vc_custom.dll DESTINATION bin)
install(FILES ${wxWidgets_LIB_DIR}/wxmsw315u_core_vc_custom.dll DESTINATION bin)
else()
install(FILES ${wxWidgets_LIB_DIR}/wxbase315ud_vc_custom.dll DESTINATION bin)
install(FILES ${wxWidgets_LIB_DIR}/wxmsw315ud_core_vc_custom.dll DESTINATION bin)
endif()
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "0")
set(CPACK_PACKAGE_VERSION_MINOR "1")
include(CPack)
Look I added this below :
if(CMAKE_BUILD_TYPE MATCHES Release)
install(FILES ${wxWidgets_LIB_DIR}/wxbase315u_vc_custom.dll DESTINATION bin)
install(FILES ${wxWidgets_LIB_DIR}/wxmsw315u_core_vc_custom.dll DESTINATION bin)
else()
install(FILES ${wxWidgets_LIB_DIR}/wxbase315ud_vc_custom.dll DESTINATION bin)
install(FILES ${wxWidgets_LIB_DIR}/wxmsw315ud_core_vc_custom.dll DESTINATION bin)
endif()
And It works as I wanted!

Related

CMake/CPack is inserting dynamic links instead of regular files for external shared libraries

I need to use an specific external shared library on a project. It links fine, and locally it runs like a charm.
The problem is when I need to make a distribution package. When I run cpack the output file has the symbolic links to these external shared libraries. I need it to include the external libraries as well (not just the symbolic link). How can I do it?
Here is my CMakeLists.txt
project(test VERSION 1.0.0 LANGUAGES CXX C)
set(CMAKE_CXX_STANDARD 11)
set(Protobuf_LIBRARIES $ENV{CONDA_PREFIX}/lib/libprotobuf.so)
add_executable(test main.cpp)
target_link_libraries(test
${Protobuf_LIBRARIES}
)
include(GNUInstallDirs)
install(TARGETS test
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(FILES ${Protobuf_LIBRARIES}
DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT RuntimeLibraries
)
set(CPACK_PACKAGE_NAME "Test")
include(CPack)
=== EDIT ===
Following #alex-reinking suggestion, and for the sake of completition on this question, here is the CMakeLists.txt working. It still has a problem with dependencies pointing to local dynamic libraries, so I needed to use an external app to solve that on OSX ( https://github.com/auriamg/macdylibbundler/ ). Be aware that, on this example, I'm including a Linux library.
project(test VERSION 1.0.0 LANGUAGES CXX C)
set(CMAKE_CXX_STANDARD 11)
set(Protobuf_LIBRARIES $ENV{CONDA_PREFIX}/lib/libprotobuf.so)
add_executable(test main.cpp)
target_link_libraries(test
${Protobuf_LIBRARIES}
)
include(GNUInstallDirs)
install(TARGETS test
RUNTIME_DEPENDENCY_SET A-dependency
)
install(RUNTIME_DEPENDENCY_SET A-dependency PRE_EXCLUDE_REGEXES )
install(FILES ${MYLIB_LOCATION} DESTINATION ${CMAKE_INSTALL_LIBDIR})
set(CPACK_PACKAGE_NAME "Test")
include(CPack)```

target_link_libraries(${target} PUBLIC CGAL::Eigen3_support), what libs linked in this one?

My question is what libs linked about CGAL::Eigen3_support?
# CMakeList.txt : CMake project for XXX, include source and define
project specific logic here.
cmake_minimum_required (VERSION 3.8)
include_directories("/usr/include/eigen3")
TODO: Add tests and install targets if needed.
find_package(CGAL REQUIRED)
find_package(Eigen3 3.4.0 REQUIRED) #(3.1.0 or greater)
include(CGAL_Eigen3_support)
if(NOT TARGET CGAL::Eigen3_support)
message(
STATUS "This project requires the Eigen library, and will not be compiled.")
return()
endif()
create_single_source_cgal_program("XXX.cpp")
foreach(target XXX)
target_link_libraries(${target} PUBLIC CGAL::Eigen3_support)
endforeach()

CMake Submodules Do Not Resolve Project Dependencies on MSVC "Cannot open include files"

I am using the following cmake file:
cmake_minimum_required(VERSION 3.19)
project(Neon LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
option(LIBIGL_WITH_OPENGL "Use OpenGL" ON)
option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" ON)
option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" ON)
include(libigl)
find_package(Boost REQUIRED COMPONENTS unit_test_framework)
add_executable(Neon src/main.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}}/include>
$<INSTALL_INTERFACE:include>)
target_link_libraries(Neon PUBLIC Eigen3::Eigen igl::core igl::opengl_glfw solvers)
add_subdirectory(solvers)
I have my main executable, and I have my subdirectory "solvers" which has some other numerical routines. The CMake file for that is as follows:
project(solvers)
add_library(${PROJECT_NAME} SHARED src/LinearElastic.cpp)
target_include_directories(${PROJECT_NAME}
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src)
install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Config
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
target_link_libraries(${PROJECT_NAME} igl::core Eigen3::Eigen)
install(DIRECTORY include/ DESTINATION "${INSTALL_INCLUDE_DIR}")
install(EXPORT ${PROJECT_NAME}Config DESTINATION share/${PROJECT_NAME}/cmake)
export(TARGETS ${PROJECT_NAME} FILE ${PROJECT_NAME}Config.cmake
Eigen and IGL are both libraries which are found from the following:
if(TARGET igl::core)
return()
endif()
include(FetchContent)
FetchContent_Declare(
libigl
GIT_REPOSITORY https://github.com/libigl/libigl.git
GIT_TAG v2.3.0
)
# Note: In libigl v3.0.0, the following will become a one-liner:
# FetchContent_MakeAvailable(libigl)
FetchContent_GetProperties(libigl)
if(NOT libigl_POPULATED)
FetchContent_Populate(libigl)
endif()
list(PREPEND CMAKE_MODULE_PATH "${libigl_SOURCE_DIR}/cmake")
include(${libigl_SOURCE_DIR}/cmake/libigl.cmake)
Building the main executable has no issues whatsoever, however, when attempting to use the dependencies from the libigl library in the submodule, I am encountering a lot of problems where the imports are unable to resolve. In particular, when attempting to use Eigen, I get "Cannot open include file" errors.
I have tried googling this issue, but none seem to cover the case when I am using a custom-written include() for a library. Ordinarily I'd just find_package in the submodules, but this doesn't seem to work correctly. I assume this is something silly, or perhaps I'm misunderstanding. Please let me know if I can improve the clarity of the question.
The particular error is here:
#ifndef NEON_LINEARELASTIC_H
#define NEON_LINEARELASTIC_H
#include <Eigen/Dense> // "Cannot include" error
class LinearElastic {
public:
Eigen::MatrixXi foobar;
auto doIt() -> void;
};
#endif//NEON_LINEARELASTIC_
I was able to solve this problem. I am typically used to a unix-based environment, so when attempting to apply the same typical thinking to windows, I encountered a few issues, namely, the way different compilers handle shared linking. To avoid rehashing what is already known, I defer to this post to allow anyone else encountering this issue to solve the problem.
I changed the CMakeLists.txt for my main executable to the following:
cmake_minimum_required(VERSION 3.19)
project(Neon LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(INSTALL_LIB_DIR lib CACHE PATH "Install directory for library code")
set(INSTALL_BIN_DIR CACHE PATH "Install directory for executables")
set(INSTALL_INCLUDE_DIR include CACHE PATH "Install directory for header files")
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
option(LIBIGL_WITH_OPENGL "Use OpenGL" ON)
option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" ON)
option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" ON)
include(libigl)
if(MSVC) // This line fixed it!
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
set(BUILD_SHARED_LIBS TRUE)
endif()
foreach(p LIB BIN INCLUDE CMAKE)
set(var INSTALL_${p}_DIR)
if(NOT IS_ABSOLUTE "${${var}}")
set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
endif()
endforeach()
find_package(Boost REQUIRED COMPONENTS unit_test_framework)
include_directories("${PROJECT_SOURCE_DIR}"
"${PROJECT_BINARY_DIR}")
add_executable(Neon src/main.cpp)
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}}/include>
$<INSTALL_INTERFACE:include>)
target_link_libraries(Neon PRIVATE Eigen3::Eigen igl::core igl::opengl_glfw solvers)
add_subdirectory(solvers)
By setting the windows-specific options, the app was able to build and run without issue.

Cannot find good include directory and lib in my project after find_package

I'm building my own library using this CMakeLists.txt :
PROJECT (AstroLib)
cmake_minimum_required(VERSION 3.0)
set(AALib_VERSION_MAJOR 1 CACHE STRING "major version" FORCE)
set(AALib_VERSION_MINOR 95 CACHE STRING "minor version" FORCE)
set(AALib_VERSION ${AALib_VERSION_MAJOR}.${AALib_VERSION_MINOR} CACHE STRING "version" FORCE)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
include(GenerateExportHeader)
file(GLOB AALib_SRCS "AALIb/source/*.cpp")
file(GLOB AALib_Headers "AALIb/include/*.h" "AALIb/include/*.hpp")
message ("AALib_VERSION ${AALib_VERSION}")
message ("CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}")
message ("CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}")
add_library (AALib STATIC ${AALib_SRCS})
target_include_directories(AALib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/AALib/include>
$<INSTALL_INTERFACE:include>
PRIVATE AALib/source)
generate_export_header( AALib )
set_property(TARGET AALib PROPERTY VERSION ${AALib_VERSION})
install(TARGETS AALib EXPORT AALibConfig
LIBRARY DESTINATION "lib/${CMAKE_BUILD_TYPE}"
ARCHIVE DESTINATION "lib/${CMAKE_BUILD_TYPE}"
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AALib_export.h" DESTINATION include COMPONENT Devel)
install(FILES ${AALib_Headers} DESTINATION include)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/AALib/AALibConfigVersion.cmake"
VERSION ${AALib_VERSION}
COMPATIBILITY AnyNewerVersion
)
export(TARGETS AALib
FILE "${CMAKE_CURRENT_BINARY_DIR}/AALib/AALibConfig.cmake"
NAMESPACE Upstream::
)
install(EXPORT AALibConfig DESTINATION AALib/cmake)
set(FOO "rtatzera")
#configure_file(AALibTargets.cmake "${CMAKE_CURRENT_BINARY_DIR}/AALib/AALibConfig.cmake" COPYONLY)
set(ConfigPackageLocation lib/cmake/AALib)
message ("ConfigPackageLocation ${ConfigPackageLocation}")
install(EXPORT AALibConfig
FILE
AALibConfig.cmake
NAMESPACE
Upstream::
DESTINATION
${ConfigPackageLocation}
)
I run cmake-gui with this cmakelists.txt and I can build and install my library on my computer.
Now I want to use this lib in another project using this cmakelists.txt :
cmake_minimum_required(VERSION 3.0)
PROJECT (DataMeteo)
find_package(OpenCV REQUIRED)
find_package(AALib REQUIRED)
file(GLOB DataMeteo_SRCS
"*.h"
"*.cpp")
ADD_EXECUTABLE (DataMeteo ${DataMeteo_SRCS})
message ( "AALib = ${AAlib}")
if (OpenCV_FOUND AND AALib_FOUND)
target_link_libraries( DataMeteo PUBLIC ${AALIb_} ${OpenCV_LIBS})
else (OpenCV_FOUND AND AALib_FOUND)
message("OPENC not found or AALib NOT FOUND ")
endif (OpenCV_FOUND AND AALib_FOUND)
In VS project I can find all opencv libs and include but I cannot find include and lib of my own Library. There is no error when I run cmake-gui.
Where is error(s) in my code (cmakelists.txt)?
Configuration Windows 10 64 bits VS2017 CMake 3.11.0

Change default CMakeLists.txt created by KDevelop?

When I create a project, my CMakeLists.txt file looks like this:
cmake_minimum_required(VERSION 2.6)
project(testttt)
add_executable(testttt main.cpp)
install(TARGETS testttt RUNTIME DESTINATION bin)
But I want it to looks like this:
cmake_minimum_required(VERSION 2.6)
project(testttt)
add_executable(testttt main.cpp)
install(TARGETS testttt RUNTIME DESTINATION bin)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
so that I have C++11 support by default. How do I do it?
KDevelop project templates are implemented using Grantlee templating engine. Here is a manual how to add your own template.
Built-in templates are located in /share/apps/kdevfiletemplates/templates, you can use "Basic C++ project` as an example.