diff --git a/cmake/platform/windows.cmake b/cmake/platform/windows.cmake index 5fca89b57..35e61be15 100644 --- a/cmake/platform/windows.cmake +++ b/cmake/platform/windows.cmake @@ -9,16 +9,34 @@ if(NOT DEFINED BUILD_SHARED_LIBS) endif() # Windows/cmake make things difficult if building dll's. -# These use RUNTIME_OUTPUT_DIRECTORY (aka bin) and can't be -# distinguished from exe's. We want exe output directory to be -# in the package's local folder (see catkin_project) - but dlls -# to be public - ${CMAKE_BINARY_DIR}/bin. -# -# This is an awful hack - we want to move away from redefining +# By default: +# .dll -> CMAKE_RUNTIME_OUTPUT_DIRECTORY +# .exe -> CMAKE_RUNTIME_OUTPUT_DIRECTORY +# .lib -> CMAKE_LIBRARY_OUTPUT_DIRECTORY +# +# Subsequently, .dll's and .exe's use the same variable and by +# default must be installed to the same place. Which is not +# what we want for catkin. We wish: +# +# .dll -> CATKIN_GLOBAL_BIN_DESTINATION +# .exe -> CATKIN_PACKAGE_BIN_DESTINATION +# .lib -> CATKIN_PACKAGE_LIB_DESTINATION +# +# Since we can't put CMAKE_RUNTIME_OUTPUT_DIRECTORY to +# two values at once, we have this ugly workaround here. +# +# Note - we want to move away from redefining # add_library style calls, but necessary until a better solution # is available for windows. Alternatives are to set_target_properties # on every lib (painful) or to make exe's public (name conflicts # bound to arise). +# +# Another feature that would be desirable, is to install .pdb's for +# debugging along with the library. Can't do that here as we do not +# know for sure if the library target is intended for installation +# or not. Might a good idea to have a script that searches for all +# pdb's under CATKIN_DEVEL_PREFIX and copies them over at the end +# of the cmake build. if(BUILD_SHARED_LIBS) if(WIN32) function(add_library library) @@ -26,28 +44,13 @@ if(BUILD_SHARED_LIBS) list(FIND ARGN "IMPORTED" FIND_POS) _add_library(${ARGV0} ${ARGN}) if(${FIND_POS} EQUAL -1) - # It is not imported, add our custom copy rule - add_custom_command(TARGET ${ARGV0} POST_BUILD - #cmake -E copy_if_different ${ARGV0}.dll ${CMAKE_BINARY_DIR}/bin # Doesn't handle regexp, i.e. dll* - # uglier than above, but bruce force copies all the windows rubbish as well (.pdb, .manifest, .txt etc). - COMMAND if exist "${PROJECT_BINARY_DIR}/bin/${ARGV0}.dll" ( cp bin/${ARGV0}* ${CMAKE_BINARY_DIR}/bin ) - WORKING_DIRECTORY ${PROJECT_BINARY_DIR}) - # Quite likely, linux guys hacking packages will not think to set the runtime destination to bin - # for dll's and this will create a huge headache in porting. Just do it here for now. - # From cmake docs - 'Installing a target with EXCLUDE_FROM_ALL set to true has undefined behavior.' - get_target_property(${ARGV0}_EXCLUDE_FROM_INSTALL ${ARGV0} EXCLUDE_FROM_ALL) - if(NOT ${${ARGV0}_EXCLUDE_FROM_INSTALL}) - install(TARGETS ${ARGV0} - RUNTIME DESTINATION bin - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) - if(NOT CMAKE_BUILD_TYPE STREQUAL "Release") - install(FILES ${CMAKE_BINARY_DIR}/bin/${ARGV0}.pdb DESTINATION bin) - endif() - endif() + set_target_properties(${ARGV0} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION} + LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_LIB_DESTINATION} + ARCHIVE_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_LIB_DESTINATION} + ) endif() endfunction() - # Almost impossible to do the same as above to install .pdb's for exe's as we do not know their - # runtime destinations. Sometimes the runtime destination is bin, sometimes it is _pkg_name_/bin. endif() endif()