diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-16 07:54:06 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-16 07:54:06 +0000 |
| commit | 9226e87baacece10ea4971a9588d46e30cc23492 (patch) | |
| tree | fe2729d2bf6c07366e71a6d39421ff05b239b713 /cmake | |
| parent | c4565386553ea86308a9487650d2435804893ed0 (diff) | |
feat(driver): embed native compilation and link resources
Link LLVM, the Clang driver and LLD statically, and embed native link inputs
so executable generation needs no installed development toolchain.
Keep glibc dynamically linked on Linux.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'cmake')
| -rw-r--r-- | cmake/EmbeddedLLVM.cmake | 2 | ||||
| -rw-r--r-- | cmake/NativeCompiler.cmake | 110 |
2 files changed, 111 insertions, 1 deletions
diff --git a/cmake/EmbeddedLLVM.cmake b/cmake/EmbeddedLLVM.cmake index c7ad5d4..cb08edc 100644 --- a/cmake/EmbeddedLLVM.cmake +++ b/cmake/EmbeddedLLVM.cmake @@ -17,7 +17,7 @@ foreach(cpsc_dependency IN LISTS cpsc_support_libs) cpsc_find_library(CPSC_STATIC_${cpsc_library_name} ${cpsc_library_names}) if(NOT CPSC_STATIC_${cpsc_library_name}) message(FATAL_ERROR - "EMBEDDED requires a static archive for ${cpsc_dependency}; download or install its development package") + "cpsc requires a static archive for ${cpsc_dependency}; download or install its development package") endif() string(REPLACE "${cpsc_dependency}" "${CPSC_STATIC_${cpsc_library_name}}" cpsc_support_libs "${cpsc_support_libs}") diff --git a/cmake/NativeCompiler.cmake b/cmake/NativeCompiler.cmake new file mode 100644 index 0000000..8371ee2 --- /dev/null +++ b/cmake/NativeCompiler.cmake @@ -0,0 +1,110 @@ +# 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") +find_package(Python3 3.9 REQUIRED COMPONENTS Interpreter) + +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() + +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.py") +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${cpsc_runtime_generator}") +execute_process(COMMAND "${Python3_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}) +# 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 are not driver/linker dependencies and may reference + # optional packages absent from binary SDK installations. + if(cpsc_llvm_library MATCHES "^LLVM(LineEditor|BOLT.*|Exegesis.*|OptDriver)$") + 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() +foreach(cpsc_native_library clangDriver ${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}") + endif() +endforeach() |
