问题
I have set up cross-platform software project using CMake Superbuild, where dependencies are added and built using ExternalProject_Add
. The project compiles on both Windows and Linux, but when I try to run the executable programs that are produced, it does not work because it fails to find dll/so files of dependencies. This is not surprising, as the dll/so files of external dependencies are not placed in the output directory(bin
in visualization below).
One of the dependencies that are added using ExternalProject_Add
is OpenCV. After OpenCv is built by the superbuild, I can find it using find_package(OpenCv)
. I can then reference libraries and include files by using the variables OpenCV_LIBS
and OpenCV_INCLUDE_DIRS
. However, there seems to be no variables that tell me where the dll/so files are located.
To further complicate it, it seems that the dll/so files end up in different folders when building on Linux and Windows. Here is simplified visualization of my project structure. Build/bin
is where my executable programs and dll/so files that my project produces end up.
|-- Project1
| |-- Source1.cpp
|-- Project2
| |-- Source2.cpp
|-- CMake
| |-- Superbuild.cmake
|-- CMakeLists.txt
|-- Build
| |-- External_projects
| |-- Bin
On Windows, the OpenCV dlls end up in the external_projects
folder: external_projects/OpenCV-build/bin/Debug
, wheras on Linux the .so files end up in external_projects/OpenCV-build/lib
.
I guess I could for each external project check where the dll/so files end up, and copy them by using a combination of GLOB and if(WIN32)
etc. But this doesn't seem ideal.
What is the proper way of doing this in a CMake superbuild, how do you make the dll/so files available so the executable programs can find them?
Update To clarify: There is a CMakeLists.txt file inside the CMake folder. This script calls Superbuild.cmake which (somewhat simplified) looks like this:
ExternalProject_Add(OpenCV ...) # Downloads source from github
ExternalProject_Add(libtiff...)# Downloads source from gitlab
...
ExternalProject_Add(myMainProject
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/.. # Adds CMakeLists.txt in root project folder
DEPENDS ${myMainProjectDependencies} # OpenCV and libtiff
)
This results in the dependencies being built before myMainProject is built.
回答1:
You can setup an install target with CMake, and configure it to place your binaries and headers in the correct location:
# bin
if (${BUILD_SHARED_LIBS})
install(
FILES
$<TARGET_FILE:my_target>
DESTINATION
bin
COMPONENT
runtime
)
endif()
# lib
install(
TARGETS
my_target
DESTINATION
lib
COMPONENT
devel
)
# include
install(
FILES
Header1.hpp
Header2.hpp
DESTINATION
include/my_target
COMPONENT
devel
)
Now you can install the binaries, import libraries, and headers to your CMAKE_INSTALL_PREFIX
path, using something like ninja install
(assuming you're using Ninja as the generator for CMake).
来源:https://stackoverflow.com/questions/58933367/how-to-find-dll-so-files-in-a-cmake-superbuild