-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathextract_info.cmake
More file actions
78 lines (67 loc) · 3.07 KB
/
Copy pathextract_info.cmake
File metadata and controls
78 lines (67 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
cmake_minimum_required(VERSION 3.20)
set(EXTRACT_INFO_TARGET_TYPES EXECUTABLE SHARED_LIBRARY)
# https://stackoverflow.com/questions/60211516/programmatically-get-all-targets-in-a-cmake-project
function(get_all_targets _result _dir)
get_property(_subdirs DIRECTORY "${_dir}" PROPERTY SUBDIRECTORIES)
foreach(_subdir IN LISTS _subdirs)
get_all_targets(${_result} "${_subdir}")
endforeach()
get_directory_property(_sub_targets DIRECTORY "${_dir}" BUILDSYSTEM_TARGETS)
set(${_result} ${${_result}} ${_sub_targets} PARENT_SCOPE)
endfunction()
function(get_target_sources SOURCES TARGET)
get_target_property(TARGET_DIR ${TARGET} SOURCE_DIR)
get_target_property(TARGET_SOURCES_RAW ${TARGET} SOURCES)
set(TARGET_SOURCES "")
if(NOT TARGET_SOURCES_RAW)
message(STATUS " No sources found for ${TARGET} in ${TARGET_DIR}")
else()
foreach(TARGET_SOURCE ${TARGET_SOURCES_RAW})
# Complex projects may contain generator expressions so we handle that here since there is no way to evaluate that expression
if(TARGET_SOURCE MATCHES "\\$<TARGET_OBJECTS:([^>]+)>")
set(SOURCE_TARGET ${CMAKE_MATCH_1})
if(TARGET "${SOURCE_TARGET}")
get_target_sources(SOURCE_SOURCES ${SOURCE_TARGET})
if(SOURCE_SOURCES)
list(APPEND TARGET_SOURCES ${SOURCE_SOURCES})
endif()
endif()
else()
if(NOT IS_ABSOLUTE "${TARGET_SOURCE}")
set(TARGET_SOURCE "${TARGET_DIR}/${TARGET_SOURCE}")
endif()
list(APPEND TARGET_SOURCES ${TARGET_SOURCE})
endif()
endforeach()
endif()
set(${SOURCES} ${TARGET_SOURCES} PARENT_SCOPE)
endfunction()
function(extract_info)
message(STATUS "Detecting targets ...")
get_all_targets(ALL_TARGETS ${PROJECT_SOURCE_DIR})
foreach(TARGET ${ALL_TARGETS})
get_target_property(TARGET_TYPE ${TARGET} TYPE)
if(NOT TARGET_TYPE IN_LIST EXTRACT_INFO_TARGET_TYPES)
message(STATUS " Skipping ${TARGET_TYPE} ${TARGET}")
continue()
endif()
get_target_property(TARGET_LINK_LIBRARIES ${TARGET} LINK_LIBRARIES)
message(STATUS " Found ${TARGET_TYPE} ${TARGET}")
# Recursively get target sources and shared library/object sources
get_target_sources(TARGET_SOURCES ${TARGET})
foreach(LINK_TARGET IN LISTS TARGET_LINK_LIBRARIES)
if(TARGET ${LINK_TARGET})
get_target_sources(LINK_SOURCES ${LINK_TARGET})
list(APPEND TARGET_SOURCES ${LINK_SOURCES})
endif()
endforeach()
list(JOIN TARGET_SOURCES "\n" TARGET_SOURCES)
if(${TARGET_TYPE} STREQUAL "EXECUTABLE")
set(TARGET_NAME $<TARGET_FILE_NAME:${TARGET}>)
else()
set(TARGET_NAME $<TARGET_LINKER_FILE_NAME:${TARGET}>)
endif()
file(GENERATE OUTPUT "${TARGET_NAME}.sources" CONTENT "${TARGET_SOURCES}")
endforeach()
endfunction()
cmake_language(DEFER CALL extract_info)