我正在构建一个动态库,它可以像插件一样动态加载。如果存在,则加载库。如果不存在,它就不能存在。
当然,我制作了一个测试应用程序......但它没有用。
的CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
PROJECT(MYLIB)
enable_testing()
INCLUDE(CPack)
SET(SRCS
src/source1.cpp
src/source2.cpp
)
ADD_LIBRARY(mylib SHARED ${SRCS})
ADD_SUBDIRECTORY(test)
测试/的CMakeLists.txt
ADD_EXECUTABLE(test_loader main.c)
TARGET_LINK_LIBRARIES(test_loader dl)
ADD_TEST(NAME test_loader COMMAND test_loader)
测试/ main.c中
#include <dlfcn.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
void* handle;
handle = dlopen("./mylib.so", RTLD_LAZY);
if (handle == 0)
{
fprintf(stderr, "%s\n", dlerror());
}
return 1;
}
然后构建
mkdir build
cd build
cmake ..
make
结果是mylib.so
中有/build
个文件。 test_loader
中有/build/test
个可执行文件。
这并没有成功。
我需要的是mylib.so
下/build/test/
的副本,以便我可以使用测试应用动态加载它。
答案 0 :(得分:2)
虽然给出的答案对我有很大的帮助(任何读这篇文章的人都应该回顾这些答案以及评论),但我找到了更好的解决方案:
add_custom_command(TARGET test_loader POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:mylib>" $<TARGET_FILE_DIR:test_loader>)
此解决方案会生成两个库副本。一个副本位于test_loader旁边,因此单元测试可以正常工作。另一个是默认输出位置。由于它仍处于默认输出位置,因此依赖mylib
的其他项目默认知道在哪里找到它们。
答案 1 :(得分:0)
有cmake变量可以让您控制库,共享库和可执行文件的放置位置。请参阅cmake文档Variables that Control the Build。我认为混合可执行文件和库不是一个好主意。 (当然这是我的意见 - 你可以使用你想要的任何布局。)我使用以下内容:
redirect()->guest('custom');
如果您使用了这个,那么您需要将dlopen语句调整为# Directory for output files
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
CACHE PATH "Output directory for static libraries.")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
CACHE PATH "Output directory for shared libraries.")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
CACHE PATH "Output directory for executables and DLL's.")
请注意,我调整了mylib的名称,因为我相信cmake在Linux上默认使用handle = dlopen("../lib/libmylib.so", RTLD_LAZY);
前缀在命名库时。