blob: 5ff49cb40c728f372112fe93ed09c4aba209d804 (
plain)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# Native output is independent of the optional -r execution engine.
find_package(Clang REQUIRED CONFIG HINTS "${LLVM_INSTALL_PREFIX}/lib/cmake/clang")
cpsc_find_dependency(PATH LLD_DIR NAMES LLDConfig.cmake PATH_SUFFIXES lib/cmake/lld cmake)
find_package(LLD REQUIRED CONFIG HINTS "${LLVM_INSTALL_PREFIX}/lib/cmake/lld")
cpsc_find_dependency(PROGRAM PERL_EXECUTABLE NAMES perl REQUIRED)
find_package(Perl REQUIRED)
if(NOT LLVM_ENABLE_ZLIB)
message(FATAL_ERROR "Native link resources require LLVM built with zlib support")
endif()
if(MINGW)
set(cpsc_native_platform windows)
set(cpsc_linker_libraries lldMinGW lldCOFF)
elseif(APPLE)
set(cpsc_native_platform macos)
set(cpsc_linker_libraries lldMachO)
else()
set(cpsc_native_platform linux)
set(cpsc_linker_libraries lldELF)
endif()
foreach(cpsc_native_library clangDriver clangCodeGen ${cpsc_linker_libraries})
get_target_property(cpsc_native_type ${cpsc_native_library} TYPE)
if(NOT cpsc_native_type STREQUAL "STATIC_LIBRARY")
message(FATAL_ERROR "Native output requires static ${cpsc_native_library}; found ${cpsc_native_type}. See doc/build.md for static dependency setup.")
endif()
endforeach()
set(cpsc_native_flags)
get_filename_component(cpsc_lld_prefix "${LLD_DIR}/../../.." ABSOLUTE)
if(APPLE)
set(cpsc_linker_names ld64.lld)
else()
set(cpsc_linker_names ld.lld-23 ld.lld)
endif()
find_program(CPSC_NATIVE_LINKER NAMES ${cpsc_linker_names}
HINTS "${cpsc_lld_prefix}/bin" ${CPSC_LOCAL_BIN_DIRS})
if(NOT CPSC_NATIVE_LINKER)
message(FATAL_ERROR "Install the LLD 23 executable to prepare native link resources")
endif()
list(APPEND cpsc_native_flags "--flag=--ld-path=${CPSC_NATIVE_LINKER}")
target_link_options(cpsc PRIVATE -fuse-ld=lld "--ld-path=${CPSC_NATIVE_LINKER}")
if(CMAKE_SYSROOT)
list(APPEND cpsc_native_flags "--flag=--sysroot=${CMAKE_SYSROOT}")
endif()
if(APPLE)
if(NOT CMAKE_OSX_SYSROOT)
execute_process(COMMAND xcrun --show-sdk-path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE cpsc_sdk_result)
if(NOT cpsc_sdk_result EQUAL 0)
message(FATAL_ERROR "Cannot locate the macOS SDK")
endif()
endif()
list(APPEND cpsc_native_flags "--flag=-isysroot" "--flag=${CMAKE_OSX_SYSROOT}")
if(CMAKE_OSX_DEPLOYMENT_TARGET)
list(APPEND cpsc_native_flags "--flag=-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()
endif()
set(cpsc_runtime_generator "${CMAKE_SOURCE_DIR}/tools/driver/prepare-native-runtime.pl")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${cpsc_runtime_generator}")
execute_process(COMMAND "${PERL_EXECUTABLE}" "${cpsc_runtime_generator}"
"--compiler=${CMAKE_CXX_COMPILER}"
"--output=${CMAKE_BINARY_DIR}/native-runtime/NativeRuntime.inc"
"--platform=${cpsc_native_platform}" ${cpsc_native_flags}
RESULT_VARIABLE cpsc_runtime_result OUTPUT_VARIABLE cpsc_runtime_output
ERROR_VARIABLE cpsc_runtime_error)
if(NOT cpsc_runtime_result EQUAL 0)
message(FATAL_ERROR "Cannot prepare native link resources: ${cpsc_runtime_error}")
endif()
message(STATUS "${cpsc_runtime_output}")
include("${CMAKE_BINARY_DIR}/native-runtime/native-runtime-inputs.cmake")
target_sources(cpsc PRIVATE tools/driver/NativeCompiler.cc)
target_include_directories(cpsc PRIVATE ${CLANG_INCLUDE_DIRS} ${LLD_INCLUDE_DIRS}
"${CMAKE_BINARY_DIR}/native-runtime")
target_link_libraries(cpsc PRIVATE clangDriver ${cpsc_linker_libraries})
# EXTERN signatures use clang's C ABI code (lib/CodeGen/CABI/ClangABI.cc).
target_include_directories(CPSCodeGen PRIVATE ${CLANG_INCLUDE_DIRS})
target_link_libraries(CPSCodeGen PRIVATE clangCodeGen clangDriver)
if(MINGW AND TARGET LibXml2::LibXml2)
# LLD's COFF manifest support reaches libxml2 through LLVMWindowsManifest.
# An explicit .dll.a in that interface bypasses the driver's -static flag.
cpsc_find_dependency(LIBRARY CPSC_STATIC_xml2 REQUIRED NAMES libxml2.a)
cpsc_find_dependency(LIBRARY CPSC_STATIC_iconv REQUIRED NAMES libiconv.a)
add_library(CPSCStaticXML2 INTERFACE)
# The prebuilt LLVM archive uses dllimport references. Load XML definitions
# before LLD resolves those references to local symbols.
target_link_libraries(CPSCStaticXML2 INTERFACE
-Wl,--whole-archive "${CPSC_STATIC_xml2}" -Wl,--no-whole-archive
"${CPSC_STATIC_iconv}" "${CPSC_STATIC_z}" bcrypt)
get_target_property(cpsc_manifest_libs LLVMWindowsManifest INTERFACE_LINK_LIBRARIES)
list(TRANSFORM cpsc_manifest_libs REPLACE "^LibXml2::LibXml2$" CPSCStaticXML2)
set_property(TARGET LLVMWindowsManifest PROPERTY INTERFACE_LINK_LIBRARIES "${cpsc_manifest_libs}")
endif()
# Distribution Clang/LLD archives can still name the shared LLVM umbrella
# library in their imported interfaces. Resolve those edges to static archives.
add_library(CPSCStaticLLVM INTERFACE)
foreach(cpsc_llvm_library IN LISTS LLVM_AVAILABLE_LIBS)
# Standalone tools and HTTP/debuginfod clients are not driver/linker
# dependencies. Keep their optional LibEdit/CURL packages optional.
if(cpsc_llvm_library MATCHES "^LLVM(LineEditor|BOLT.*|Exegesis.*|OptDriver|HTTP|Debuginfod)$")
continue()
endif()
if(TARGET ${cpsc_llvm_library})
get_target_property(cpsc_llvm_type ${cpsc_llvm_library} TYPE)
if(cpsc_llvm_type STREQUAL "STATIC_LIBRARY")
target_link_libraries(CPSCStaticLLVM INTERFACE ${cpsc_llvm_library})
endif()
endif()
endforeach()
foreach(cpsc_import IN LISTS CLANG_EXPORTED_TARGETS LLD_EXPORTED_TARGETS LLVM_AVAILABLE_LIBS)
if(NOT TARGET ${cpsc_import})
continue()
endif()
get_target_property(cpsc_interface ${cpsc_import} INTERFACE_LINK_LIBRARIES)
if(cpsc_interface)
list(FIND cpsc_interface LLVM cpsc_shared_llvm_index)
if(NOT cpsc_shared_llvm_index EQUAL -1)
list(REMOVE_ITEM cpsc_interface LLVM)
if(NOT cpsc_import IN_LIST LLVM_AVAILABLE_LIBS)
list(APPEND cpsc_interface CPSCStaticLLVM)
endif()
endif()
if(CPSC_STATIC_z)
list(TRANSFORM cpsc_interface REPLACE "^ZLIB::ZLIB$" "${CPSC_STATIC_z}")
endif()
if(CPSC_STATIC_zstd)
list(TRANSFORM cpsc_interface REPLACE "^zstd::libzstd.*$" "${CPSC_STATIC_zstd}")
endif()
set_property(TARGET ${cpsc_import} PROPERTY INTERFACE_LINK_LIBRARIES "${cpsc_interface}")
endif()
endforeach()
|