-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[feat] Compatibility: CMake < 3.21 can also copy dlls
- Loading branch information
1 parent
3671f9d
commit 7cb05b7
Showing
7 changed files
with
219 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
# Author: Zhuo Zhang <[email protected]> | ||
# Homepage: https://github.com/zchrissirhcz/rocbuild | ||
|
||
cmake_minimum_required(VERSION 3.21) | ||
cmake_minimum_required(VERSION 3.10) | ||
|
||
# CMake 3.10: include_guard() | ||
# CMake 3.21: $<TARGET_RUNTIME_DLLS:tgt> | ||
|
@@ -47,10 +47,118 @@ macro(rocbuild_enable_ninja_colorful_output) | |
endmacro() | ||
|
||
|
||
function(rocbuild_copy_dll target) | ||
add_custom_command(TARGET ${target} POST_BUILD | ||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RUNTIME_DLLS:${target}> $<TARGET_FILE_DIR:${target}> | ||
COMMAND_EXPAND_LISTS | ||
# Transitively list all link libraries of a target (recursive call) | ||
# Modified from https://github.com/libigl/libigl/blob/main/cmake/igl/igl_copy_dll.cmake, GPL-3.0 / MPL-2.0 | ||
function(rocbuild_get_dependencies_recursive OUTPUT_VARIABLE TARGET) | ||
get_target_property(_aliased ${TARGET} ALIASED_TARGET) | ||
if(_aliased) | ||
set(TARGET ${_aliased}) | ||
endif() | ||
|
||
get_target_property(_IMPORTED ${TARGET} IMPORTED) | ||
get_target_property(_TYPE ${TARGET} TYPE) | ||
if(_IMPORTED OR (${_TYPE} STREQUAL "INTERFACE_LIBRARY")) | ||
get_target_property(TARGET_DEPENDENCIES ${TARGET} INTERFACE_LINK_LIBRARIES) | ||
else() | ||
get_target_property(TARGET_DEPENDENCIES ${TARGET} LINK_LIBRARIES) | ||
endif() | ||
|
||
set(VISITED_TARGETS ${${OUTPUT_VARIABLE}}) | ||
foreach(DEPENDENCY IN ITEMS ${TARGET_DEPENDENCIES}) | ||
if(TARGET ${DEPENDENCY}) | ||
get_target_property(_aliased ${DEPENDENCY} ALIASED_TARGET) | ||
if(_aliased) | ||
set(DEPENDENCY ${_aliased}) | ||
endif() | ||
|
||
if(NOT (DEPENDENCY IN_LIST VISITED_TARGETS)) | ||
list(APPEND VISITED_TARGETS ${DEPENDENCY}) | ||
rocbuild_get_dependencies_recursive(VISITED_TARGETS ${DEPENDENCY}) | ||
endif() | ||
endif() | ||
endforeach() | ||
set(${OUTPUT_VARIABLE} ${VISITED_TARGETS} PARENT_SCOPE) | ||
endfunction() | ||
|
||
# Transitively list all link libraries of a target | ||
function(rocbuild_get_dependencies OUTPUT_VARIABLE TARGET) | ||
set(DISCOVERED_TARGETS "") | ||
rocbuild_get_dependencies_recursive(DISCOVERED_TARGETS ${TARGET}) | ||
set(${OUTPUT_VARIABLE} ${DISCOVERED_TARGETS} PARENT_SCOPE) | ||
endfunction() | ||
|
||
# Copy .dll dependencies to a target executable's folder. This function must be called *after* all the CMake | ||
# dependencies of the executable target have been defined, otherwise some .dlls might not be copied to the target | ||
# folder. | ||
function(rocbuild_copy_dlls target) | ||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.21") | ||
add_custom_command(TARGET ${target} POST_BUILD | ||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RUNTIME_DLLS:${target}> $<TARGET_FILE_DIR:${target}> | ||
COMMAND_EXPAND_LISTS | ||
) | ||
return() | ||
endif() | ||
|
||
# Sanity checks | ||
if(CMAKE_CROSSCOMPILING OR (NOT WIN32)) | ||
return() | ||
endif() | ||
|
||
if(NOT TARGET ${target}) | ||
message(STATUS "rocbuild_copy_dlls() was called with a non-target: ${target}") | ||
return() | ||
endif() | ||
|
||
# Sanity checks | ||
get_target_property(TYPE ${target} TYPE) | ||
if(NOT ${TYPE} STREQUAL "EXECUTABLE") | ||
message(FATAL_ERROR "rocbuild_copy_dlls() was called on a non-executable target: ${target}") | ||
endif() | ||
|
||
# set the name of file to be written | ||
if(DEFINED CMAKE_CONFIGURATION_TYPES) | ||
set(COPY_SCRIPT "${CMAKE_BINARY_DIR}/rocbuild_copy_dlls_${target}_$<CONFIG>.cmake") | ||
else() | ||
set(COPY_SCRIPT "${CMAKE_BINARY_DIR}/rocbuild_copy_dlls_${target}.cmake") | ||
endif() | ||
|
||
add_custom_command( | ||
TARGET ${target} | ||
PRE_LINK | ||
COMMAND ${CMAKE_COMMAND} -E touch "${COPY_SCRIPT}" | ||
COMMAND ${CMAKE_COMMAND} -P "${COPY_SCRIPT}" | ||
COMMENT "Copying dlls for target ${target}" | ||
) | ||
|
||
# Retrieve all target dependencies | ||
rocbuild_get_dependencies(TARGET_DEPENDENCIES ${target}) | ||
|
||
set(DEPENDENCY_FILES "") | ||
foreach(DEPENDENCY IN LISTS TARGET_DEPENDENCIES) | ||
get_target_property(TYPE ${DEPENDENCY} TYPE) | ||
if(NOT (${TYPE} STREQUAL "SHARED_LIBRARY" OR ${TYPE} STREQUAL "MODULE_LIBRARY")) | ||
continue() | ||
endif() | ||
string(APPEND DEPENDENCY_FILES " $<TARGET_FILE:${DEPENDENCY}> # ${DEPENDENCY}\n") | ||
endforeach() | ||
|
||
set(COPY_SCRIPT_CONTENT "") | ||
string(APPEND COPY_SCRIPT_CONTENT | ||
"set(dependency_files \n${DEPENDENCY_FILES})\n\n" | ||
"list(REMOVE_DUPLICATES dependency_files)\n\n" | ||
"foreach(file IN ITEMS \${dependency_files})\n" | ||
" if(EXISTS \"\${file}\")\n " | ||
"execute_process(COMMAND \${CMAKE_COMMAND} -E copy_if_different " | ||
"\"\${file}\" \"$<TARGET_FILE_DIR:${target}>/\")\n" | ||
" endif()\n" | ||
) | ||
string(APPEND COPY_SCRIPT_CONTENT "endforeach()\n") | ||
|
||
# Finally generate one script for each configuration supported by this generator | ||
message(STATUS "Populating copy rules for target: ${target}") | ||
file(GENERATE | ||
OUTPUT "${COPY_SCRIPT}" | ||
CONTENT "${COPY_SCRIPT_CONTENT}" | ||
) | ||
endfunction() | ||
|
||
|
@@ -80,9 +188,9 @@ function(rocbuild_copy_opencv_videoio_plugin_dlls target) | |
endif() | ||
|
||
if(DEFINED CMAKE_CONFIGURATION_TYPES) | ||
set(COPY_SCRIPT "${CMAKE_BINARY_DIR}/rocbuild_copy_opencv_videoio_plugin_dlls_for_${target}_$<CONFIG>.cmake") | ||
set(COPY_SCRIPT "${CMAKE_BINARY_DIR}/rocbuild_copy_opencv_videoio_plugin_dlls_${target}_$<CONFIG>.cmake") | ||
else() | ||
set(COPY_SCRIPT "${CMAKE_BINARY_DIR}/rocbuild_copy_opencv_videoio_plugin_dlls_for_${target}.cmake") | ||
set(COPY_SCRIPT "${CMAKE_BINARY_DIR}/rocbuild_copy_opencv_videoio_plugin_dlls_${target}.cmake") | ||
endif() | ||
set(COPY_SCRIPT_CONTENT "") | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
cmake_minimum_required(VERSION 3.10) | ||
project(test_copy_dlls) | ||
|
||
include(../../rocbuild.cmake) | ||
|
||
add_library(foo SHARED ../src/foo.c) | ||
target_compile_definitions(foo PRIVATE FOO_EXPORTS) | ||
target_include_directories(foo PUBLIC ../src) | ||
set_target_properties(foo PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/foo) | ||
|
||
add_library(bar SHARED ../src/bar.c ../src/bar_internal.c) | ||
target_compile_definitions(bar PRIVATE BAR_EXPORTS) | ||
target_include_directories(bar PUBLIC ../src) | ||
set_target_properties(bar PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bar) | ||
|
||
add_library(baz SHARED ../src/baz.c) | ||
target_compile_definitions(baz PRIVATE BAZ_EXPORTS) | ||
target_include_directories(baz PUBLIC ../src) | ||
set_target_properties(baz PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/baz) | ||
target_link_libraries(baz PRIVATE foo) | ||
|
||
add_executable(test test.c) | ||
target_link_libraries(test PRIVATE bar baz) | ||
set_target_properties(test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/test) | ||
|
||
if(COPY_DLLS) | ||
rocbuild_copy_dlls(test) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include "bar.h" | ||
#include "baz.h" | ||
|
||
int main() | ||
{ | ||
return bar() + baz(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include "baz.h" | ||
#include "foo.h" | ||
|
||
int baz() | ||
{ | ||
return 2 + foo(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#pragma once | ||
|
||
#ifdef BAZ_EXPORTS | ||
# if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) | ||
# define BAZ_API __declspec(dllexport) | ||
# elif defined(__GNUC__) && __GNUC__ >= 4 | ||
# define BAZ_API __attribute__ ((visibility ("default"))) | ||
# endif | ||
#else | ||
# if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) | ||
# define BAZ_API __declspec(dllimport) | ||
# else | ||
# define BAZ_API | ||
# endif | ||
#endif | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
BAZ_API int baz(); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters