通过调用ExternalProject_Add

时间:2015-10-01 00:23:23

标签: c++ dll cmake eclipse-cdt glfw

我有一个小测试程序,我想链接到GLFW。我目前能够使用ExternalProject_Add命令下载,配置和构建.dll。当我构建我的测试程序时,我得到一个无法运行的可执行文件,因为它无法找到.dll。如果我手动将.dll复制到可执行文件所在的目录,它就可以正常运行。

如何让我的可执行文件正确链接到库?

有没有办法自动将.dll复制到需要的位置?

确保在我的程序打包时,库可以使用并且易于访问的最佳方法是什么?

的CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)
project (GLFW-test)

set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/app )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )

# Include OpenGL
find_package(OpenGL REQUIRED)
if (OPENGL_FOUND)
    include_directories(${OPENGL_INCLUDE_DIR})
    link_libraries(${OPENGL_LIBRARIES})
endif()

# Add directories for library linkage
set(GLFW_LIB_DIR ${CMAKE_BINARY_DIR}/downloads/deps/Build/GLFW_EX/src)
link_directories(${GLFW_LIB_DIR})

# Download and unpack dependencies at configure time
configure_file(deps-CMakeLists.txt downloads/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/downloads)
execute_process(COMMAND ${CMAKE_COMMAND} --build .
  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/downloads)

add_subdirectory(${CMAKE_BINARY_DIR}/downloads/deps/Source/GLFW_EX
                 ${CMAKE_BINARY_DIR}/downloads/deps/Build/GLFW_EX
                 EXCLUDE_FROM_ALL )

include_directories(${CMAKE_BINARY_DIR}/downloads/deps/Source/GLFW_EX/include)

add_executable(GLFW-test src/GLFW-test.cpp)
target_link_libraries (GLFW-test glfw3 ${OPENGL_LIBRARIES})

add_custom_command(TARGET GLFW-test POST_BUILD        # Adds a post-build event to MyTest
    COMMAND ${CMAKE_COMMAND} -E copy_if_different     # which executes "cmake - E copy_if_different..."
        "${GLFW_LIB_DIR}/glfw3.dll"                   # <--this is in-file
        $<TARGET_FILE_DIR:GLFW-test>)                 # <--this is out-file path

DEP-的CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)
project (GLFW-dl)

include(ExternalProject)
set_directory_properties(PROPERTIES EP_BASE "./deps/")

# Include GLFW
ExternalProject_Add (
       GLFW_EX
       GIT_REPOSITORY "https://github.com/glfw/glfw.git"
       GIT_TAG "master"
       CMAKE_ARGS -DGLFW_BUILD_EXAMPLES=OFF
                  -DGLFW_BUILD_TESTS=OFF
                  -DGLFW_BUILD_DOCS=OFF
                  -DGLFW_INSTALL=OFF
                  -DBUILD_SHARED_LIBS=ON
       UPDATE_COMMAND ""
       TEST_COMMAND      "" )

更新 我在此网站上描述了我使用ExternalProject_Add的方式:https://crascit.com/2015/07/25/cmake-gtest/ 它允许在项目的配置阶段仅配置和构建外部项目一次。我已经从他们的测试程序中改变了一些目录,以便在我最终添加更多外部项目时更容易一些。网站上的测试项目似乎没有考虑到我想要做的动态库。

更新2: 我已经添加了2个set命令来帮助清理CMakeLists文件顶部的构建目录。我还在底部添加了一个命令,它将从ExternalProject_Add命令构建的.dll复制到我需要的地方(最后一个可执行文件旁边)。这似乎适用于Windows,但它似乎有点hacky并且无法解决我的IDE(目前是Eclipse)中的错误。还有更好的方法吗?

有用的相关主题:

1 个答案:

答案 0 :(得分:0)

  

如何让我的可执行文件正确链接到库?

正如您的second link所述,除了将.dll与可执行文件放在同一目录中之外别无他法。

  

有没有办法自动将.dll复制到需要的位置?

在您的主项目中,您已经将变量CMAKE_RUNTIME_OUTPUT_DIRECTORY用于安装目录,其中可执行文件和.dll应在构建后放置。您可以将此变量传递给ExternalProject_add,以强制它使用相同的约定:

ExternalProject_Add (...
    CMAKE_ARGS -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
    ...
)
  

确保在我的程序打包时,库可以使用并且易于访问的最佳方法是什么?

打包只使用项目的 install-tree 。因此,将可执行文件和库安装到同一位置就足够了:

set(INSTALL_RUNTIME_DIR bin)
install(TARGETS GLFW-test
    RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR}
)
install(FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/glfw3.dll
    DESTINATION ${INSTALL_RUNTIME_DIR}
)

注意,从外部项目获得的目标GLFW_EX没有特殊类型(如可执行文件或库),因此您需要使用纯文件名安装其可交付成果。