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

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.


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.