Cmake on Windows doesn't add shared library paths (works on linux)

后端 未结 3 634
[愿得一人]
[愿得一人] 2021-01-12 08:52

I\'ve been using CMake and Eclipse on linux for a while and have been working with multiple target projects containing numerous executables and shared objects.

I use

相关标签:
3条回答
  • 2021-01-12 09:15

    Windows simply doesn't have some of the necessary concepts to allow CMake to set up your build environment. When linking Windows will look in the same directory as the binary, and then search the directories in your PATH. There isn't anything like RPATH, which is used on most Unix platforms, to inject in other more appropriate paths. The DLLs should generally be installed alongside your binaries, in the same directory.

    In my opinion, best practice on Windows is to put the DLLs next to your binaries. CMake attempts to make this easier,

    install(TARGETS MyTarget
      EXPORT "MyProjectTargets"
      RUNTIME DESTINATION "${INSTALL_RUNTIME_DIR}"
      LIBRARY DESTINATION "${INSTALL_LIBRARY_DIR}"
      ARCHIVE DESTINATION "${INSTALL_ARCHIVE_DIR}")
    

    would install DLLs to the RUNTIME destination, but put the libs in the LIBRARY destination. This means that typically on Unix-like OSes lib has the shared objects, but CMake knows that DLLs are effectively runtime and would go in bin. Hopefully this makes things clearer. It is impossible for CMake/Eclipse to really improve this much, beyond perhaps injecting additional directories into your PATH when clicking run from Eclipse (not sure if that is possible).

    If you are concerned with the build tree, then the following would work well there (as suggested in the comments below):

    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
    

    If you want to allow these to be overridden (can be useful) they should be protected with if(NOT var_name) blocks too.

    0 讨论(0)
  • 2021-01-12 09:21

    Thanks everyone for question and responses. I want just to summarize what you need to for windows support:

    Please add the following code to root CMakeLists.txt:

    # Common output directory is required for OS without rpath support.
    set (CMAKE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/result")
    set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_OUTPUT_DIRECTORY})
    set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_OUTPUT_DIRECTORY})
    set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_OUTPUT_DIRECTORY})
    

    Than you need to add working directory for every add_test:

    add_test (
      NAME ${TEST_NAME}
      COMMAND ${TEST_TARGET}
      WORKING_DIRECTORY ${CMAKE_OUTPUT_DIRECTORY}
    )
    

    Please be aware that TEST_TARGET should be unique inside current project.

    I've added windows support for lzws library using this method. You can always checkout source code and clarify remaining question.

    0 讨论(0)
  • 2021-01-12 09:23

    Just a possible answer to my own question. I think that on linux the rpath is being used to identify the locations of the dependent libraries but on windows with mingw I cannot use the elf parser and so cannot use rpath.

    0 讨论(0)
提交回复
热议问题