1enable_language(C) 2 3file(WRITE "${CMAKE_BINARY_DIR}/toplib.c" "extern void sublib1(void);\nextern void sublib2(void);\nvoid toplib(void)\n{\n sublib1();\n sublib2();\n}\n") 4add_library(toplib SHARED "${CMAKE_BINARY_DIR}/toplib.c") 5file(WRITE "${CMAKE_BINARY_DIR}/sublib1.c" "extern void sublib2(void);\nvoid sublib1(void)\n{\n sublib2();\n}\n") 6add_library(sublib1 SHARED "${CMAKE_BINARY_DIR}/sublib1.c") 7file(WRITE "${CMAKE_BINARY_DIR}/sublib2.c" "void sublib2(void)\n{\n}\n") 8add_library(sublib2 SHARED "${CMAKE_BINARY_DIR}/sublib2.c") 9target_link_libraries(toplib PRIVATE sublib1 sublib2) 10target_link_libraries(sublib1 PRIVATE sublib2) 11set_property(TARGET toplib PROPERTY INSTALL_RPATH "@loader_path/d1;@loader_path/d2") 12set_property(TARGET sublib1 PROPERTY INSTALL_RPATH "@loader_path/;@loader_path/../d2") 13install(TARGETS toplib DESTINATION lib) 14install(TARGETS sublib1 DESTINATION lib/d1) 15install(TARGETS sublib2 DESTINATION lib/d2) 16 17install(CODE [[ 18 file(GET_RUNTIME_DEPENDENCIES 19 LIBRARIES 20 "${CMAKE_INSTALL_PREFIX}/lib/$<TARGET_FILE_NAME:toplib>" 21 RPATH_PREFIX _rpaths 22 ) 23 24 set(_expected_rpath "(^|;)@loader_path/;@loader_path/\\.\\./d2$") 25 set(_actual_rpath "${_rpaths_${CMAKE_INSTALL_PREFIX}/lib/d1/$<TARGET_FILE_NAME:sublib1>}") 26 if(NOT _actual_rpath MATCHES "${_expected_rpath}") 27 message(FATAL_ERROR "Expected rpath:\n ${_expected_rpath}\nActual rpath:\n ${_actual_rpath}") 28 endif() 29 30 # Since RPATH_PREFIX is an undocumented option for install(), we don't really need the rpath 31 # for the top files anyway. 32 if(DEFINED "_rpaths_${CMAKE_INSTALL_PREFIX}/lib/$<TARGET_FILE_NAME:toplib>") 33 message(FATAL_ERROR "rpath for top library should not be defined") 34 endif() 35 ]]) 36