如何将一个目标的二进制输出复制到另一个目标的二进制文件夹中?

时间:2016-06-25 20:05:22

标签: cmake

我正在构建一个动态库,它可以像插件一样动态加载。如果存在,则加载库。如果不存在,它就不能存在。

当然,我制作了一个测试应用程序......但它没有用。

的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/的副本,以便我可以使用测试应用动态加载它。

2 个答案:

答案 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);前缀在命名库时。