Skip to content

Commit e320ede

Browse files
committed
CMake: Produce bundled output of static libraries, avoids having to carry around tiny-process-lib
1 parent 3c1507e commit e320ede

File tree

4 files changed

+130
-7
lines changed

4 files changed

+130
-7
lines changed

CMakeLists.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,15 @@ endif()
3131

3232
include(external/external.cmake)
3333

34+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
35+
3436
if(build_test AND CPPAST_TEST_GCOV AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
35-
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
3637
include(CodeCoverage)
3738
APPEND_COVERAGE_COMPILER_FLAGS()
3839
endif()
3940

41+
include(BundleStaticLibraries)
42+
4043
add_subdirectory(src)
4144

4245
if(${build_test})

cmake/BundleStaticLibraries.cmake

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# https://cristianadam.eu/20190501/bundling-together-static-libraries-with-cmake/
2+
3+
function(bundle_static_library tgt_name bundled_tgt_name)
4+
list(APPEND static_libs ${tgt_name})
5+
6+
function(_recursively_collect_dependencies input_target)
7+
set(_input_link_libraries LINK_LIBRARIES)
8+
get_target_property(_input_type ${input_target} TYPE)
9+
if (${_input_type} STREQUAL "INTERFACE_LIBRARY")
10+
set(_input_link_libraries INTERFACE_LINK_LIBRARIES)
11+
endif()
12+
get_target_property(public_dependencies ${input_target} ${_input_link_libraries})
13+
foreach(dependency IN LISTS public_dependencies)
14+
if(TARGET ${dependency})
15+
get_target_property(alias ${dependency} ALIASED_TARGET)
16+
if (TARGET ${alias})
17+
set(dependency ${alias})
18+
endif()
19+
get_target_property(_type ${dependency} TYPE)
20+
if (${_type} STREQUAL "STATIC_LIBRARY")
21+
list(APPEND static_libs ${dependency})
22+
endif()
23+
24+
get_property(library_already_added
25+
GLOBAL PROPERTY _${tgt_name}_static_bundle_${dependency})
26+
if (NOT library_already_added)
27+
set_property(GLOBAL PROPERTY _${tgt_name}_static_bundle_${dependency} ON)
28+
_recursively_collect_dependencies(${dependency})
29+
endif()
30+
endif()
31+
endforeach()
32+
set(static_libs ${static_libs} PARENT_SCOPE)
33+
endfunction()
34+
35+
_recursively_collect_dependencies(${tgt_name})
36+
37+
list(REMOVE_DUPLICATES static_libs)
38+
39+
set(bundled_tgt_full_name
40+
${CMAKE_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${bundled_tgt_name}${CMAKE_STATIC_LIBRARY_SUFFIX})
41+
42+
if (CMAKE_CXX_COMPILER_ID MATCHES "^(Clang|GNU)$")
43+
file(WRITE ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar.in
44+
"CREATE ${bundled_tgt_full_name}\n" )
45+
46+
foreach(tgt IN LISTS static_libs)
47+
file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar.in
48+
"ADDLIB $<TARGET_FILE:${tgt}>\n")
49+
endforeach()
50+
51+
file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar.in "SAVE\n")
52+
file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar.in "END\n")
53+
54+
file(GENERATE
55+
OUTPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar
56+
INPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar.in)
57+
58+
set(ar_tool ${CMAKE_AR})
59+
if (CMAKE_INTERPROCEDURAL_OPTIMIZATION)
60+
set(ar_tool ${CMAKE_CXX_COMPILER_AR})
61+
endif()
62+
63+
add_custom_command(
64+
COMMAND ${ar_tool} -M < ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.ar
65+
OUTPUT ${bundled_tgt_full_name}
66+
COMMENT "Bundling ${bundled_tgt_name}"
67+
VERBATIM)
68+
elseif(MSVC)
69+
find_program(lib_tool lib)
70+
71+
if(NOT lib_tool)
72+
get_filename_component(CXX_COMPILER_DIRECTORY "${CMAKE_CXX_COMPILER}" PATH)
73+
set(lib_tool "${CXX_COMPILER_DIRECTORY}/lib.exe")
74+
endif()
75+
76+
foreach(tgt IN LISTS static_libs)
77+
list(APPEND static_libs_full_names $<TARGET_FILE:${tgt}>)
78+
endforeach()
79+
80+
add_custom_command(
81+
COMMAND ${lib_tool} /NOLOGO /OUT:${bundled_tgt_full_name} ${static_libs_full_names}
82+
OUTPUT ${bundled_tgt_full_name}
83+
COMMENT "Bundling ${bundled_tgt_name}"
84+
VERBATIM)
85+
else()
86+
message(FATAL_ERROR "Unknown bundle scenario!")
87+
endif()
88+
89+
add_custom_target(bundling_target ALL DEPENDS ${bundled_tgt_full_name})
90+
add_dependencies(bundling_target ${tgt_name})
91+
92+
add_library(${bundled_tgt_name} STATIC IMPORTED)
93+
set_target_properties(${bundled_tgt_name}
94+
PROPERTIES
95+
IMPORTED_LOCATION ${bundled_tgt_full_name}
96+
INTERFACE_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:${tgt_name},INTERFACE_INCLUDE_DIRECTORIES>)
97+
add_dependencies(${bundled_tgt_name} bundling_target)
98+
99+
endfunction()

external/external.cmake

+7-1
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,15 @@ list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
5353
# include(HandleLLVMOptions)
5454
# add_definitions(${LLVM_DEFINITIONS})
5555
# Find the libraries that correspond to the LLVM components that we wish to use
56-
llvm_map_components_to_libnames(llvm_libs Core Support)
56+
# llvm_map_components_to_libnames(llvm_libs Core Support)
5757

5858
find_package(Clang CONFIG REQUIRED)
5959

60+
set(CLANG_LIBS
61+
libclang
62+
clangIndex
63+
)
64+
6065
message(STATUS "Found Clang (LLVM version: ${LLVM_VERSION})")
6166
message(STATUS "Include dirs: ${CLANG_INCLUDE_DIRS}")
67+
message(STATUS "Clang libraries: ${CLANG_LIBS}")

src/CMakeLists.txt

+20-5
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,15 @@ set(libclang_source
102102
libclang/type_parser.cpp
103103
libclang/variable_parser.cpp)
104104

105-
add_library(cppast ${detail_header} ${header} ${source} ${libclang_source})
105+
add_library(cppast STATIC ${detail_header} ${header} ${source} ${libclang_source})
106+
106107
target_compile_features(cppast PUBLIC cxx_std_11)
107108
target_include_directories(cppast PRIVATE ../include SYSTEM INTERFACE ../include)
108-
target_link_libraries(cppast PUBLIC type_safe _cppast_tiny_process)
109+
110+
# set(ADDITIONAL_LIBRARIES ${llvm_libs} ${CLANG_LIBS})
111+
112+
target_link_libraries(cppast type_safe _cppast_tiny_process ${ADDITIONAL_LIBRARIES})
113+
109114
target_compile_definitions(cppast PUBLIC
110115
CPPAST_VERSION_MINOR="${cppast_VERSION_MINOR}"
111116
CPPAST_VERSION_MAJOR="${cppast_VERSION_MAJOR}"
@@ -123,9 +128,19 @@ target_compile_options(cppast PRIVATE
123128
/W3>)
124129

125130

131+
132+
126133
# Link against LLVM libraries
127-
target_link_libraries(cppast PRIVATE ${llvm_libs})
128134
target_include_directories(cppast PRIVATE ${LLVM_INCLUDE_DIRS})
129-
130135
target_include_directories(cppast PRIVATE ${CLANG_INCLUDE_DIRS})
131-
target_link_libraries(cppast PRIVATE libclang)
136+
137+
bundle_static_library(cppast cppast_bundled)
138+
139+
include(CheckIPOSupported)
140+
# Optional IPO. Do not use IPO if it's not supported by compiler.
141+
# check_ipo_supported(RESULT result OUTPUT output)
142+
# if(result)
143+
# set_property(TARGET cppast_bundled PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
144+
# else()
145+
# message(WARNING "IPO is not supported: ${output}")
146+
# endif()

0 commit comments

Comments
 (0)