diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt index ef235c43f..0c7af685c 100644 --- a/Sources/CMakeLists.txt +++ b/Sources/CMakeLists.txt @@ -12,6 +12,38 @@ ## ##===----------------------------------------------------------------------===## +add_library(FoundationBuildMacros INTERFACE) +export(TARGETS FoundationBuildMacros + FILE + ${SwiftFoundation_BINARY_DIR}/cmake/modules/FoundationBuildMacros.cmake) +if(SwiftFoundation_MACRO) + message(STATUS "SwiftFoundation_MACRO provided, using macros in ${SwiftFoundation_MACRO}") + target_compile_options(FoundationBuildMacros INTERFACE + "SHELL:$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:Swift>:-plugin-path ${SwiftFoundation_MACRO}>>") +else() + message(STATUS "NO SwiftFoundation_MACRO, building macros from scratch") + include(ExternalProject) + # The macros are required for building Swift-Foundation. Build them for the + # build machine. + ExternalProject_Add(FoundationMacros + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/FoundationMacros" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/FoundationMacros" + CMAKE_ARGS + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_Swift_COMPILER=${CMAKE_Swift_COMPILER} + -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> + -DSwiftFoundation_BUILD_EXECUTABLE_MACROS=YES) + ExternalProject_Get_Property(FoundationMacros INSTALL_DIR) + add_dependencies(FoundationBuildMacros FoundationMacros) + if(CMAKE_HOST_WIN32) + set(_SwiftFoundation_HOST_EXECUTABLE_SUFFIX .exe) + endif() + + target_compile_options(FoundationBuildMacros INTERFACE + "SHELL:$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:Swift>:-load-plugin-executable ${INSTALL_DIR}/bin/FoundationMacros${_SwiftFoundation_HOST_EXECUTABLE_SUFFIX}#FoundationMacros>>") + unset(_SwiftFoundation_HOST_EXECUTABLE_SUFFIX) +endif() + add_subdirectory(_FoundationCShims) add_subdirectory(FoundationEssentials) add_subdirectory(FoundationInternationalization) diff --git a/Sources/FoundationEssentials/CMakeLists.txt b/Sources/FoundationEssentials/CMakeLists.txt index 9c1f5b462..1fc475380 100644 --- a/Sources/FoundationEssentials/CMakeLists.txt +++ b/Sources/FoundationEssentials/CMakeLists.txt @@ -49,29 +49,6 @@ add_subdirectory(String) add_subdirectory(TimeZone) add_subdirectory(URL) -if(SwiftFoundation_MACRO) - message(STATUS "SwiftFoundation_MACRO provided, using macros in ${SwiftFoundation_MACRO}") - # A path to Foundation macros was provided, so we use that path - target_compile_options(FoundationEssentials PRIVATE - "SHELL:-plugin-path ${SwiftFoundation_MACRO}") -else() - message(STATUS "SwiftFoundation_MACRO not provided, building Foundation macros locally for host") - # No path to Foundation macros was provided, so we must build it ourselves - set(FoundationMacros_BuildLocalExecutable YES) - FetchContent_Declare(FoundationMacros - SOURCE_DIR ${SwiftFoundation_SOURCE_DIR}/Sources/FoundationMacros) - FetchContent_MakeAvailable(FoundationMacros) - add_dependencies(FoundationEssentials FoundationMacros) - get_target_property(MacroDIR FoundationMacros RUNTIME_OUTPUT_DIRECTORY) - if(CMAKE_SYSTEM_NAME STREQUAL Windows) - set(MacroExecutable "${MacroDIR}/FoundationMacros.exe#FoundationMacros") - else() - set(MacroExecutable "${MacroDIR}/FoundationMacros#FoundationMacros") - endif() - target_compile_options(FoundationEssentials PUBLIC - "SHELL:$<$<COMPILE_LANGUAGE:Swift>:-load-plugin-executable ${MacroExecutable}>") -endif() - if(CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_SYSTEM_NAME STREQUAL Android) target_compile_options(FoundationEssentials PRIVATE "SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -Xcc -Xfrontend -D_GNU_SOURCE>") @@ -88,6 +65,7 @@ target_compile_options(FoundationEssentials PRIVATE ${_SwiftFoundation_wasi_libc target_compile_options(FoundationEssentials PRIVATE -package-name "SwiftFoundation") target_link_libraries(FoundationEssentials PUBLIC + FoundationBuildMacros _FoundationCShims _FoundationCollections) target_link_libraries(FoundationEssentials PUBLIC ${_SwiftFoundation_wasi_libc_libraries}) diff --git a/Sources/FoundationMacros/CMakeLists.txt b/Sources/FoundationMacros/CMakeLists.txt index 98b90c0df..0815b5884 100644 --- a/Sources/FoundationMacros/CMakeLists.txt +++ b/Sources/FoundationMacros/CMakeLists.txt @@ -26,6 +26,9 @@ endif() project(FoundationMacros LANGUAGES Swift) +option(SwiftFoundation_BUILD_EXECUTABLE_MACROS + "Build the FoundationMacros as an executable" NO) + if(NOT SWIFT_SYSTEM_NAME) if(CMAKE_SYSTEM_NAME STREQUAL Darwin) set(SWIFT_SYSTEM_NAME macosx) @@ -49,13 +52,13 @@ else() message(STATUS "SwiftSyntax_DIR provided, using swift-syntax from ${SwiftSyntax_DIR}") endif() -if(NOT FoundationMacros_BuildLocalExecutable) - add_library(FoundationMacros SHARED) - target_compile_definitions(FoundationMacros PRIVATE FOUNDATION_MACROS_LIBRARY) -else() +if(SwiftFoundation_BUILD_EXECUTABLE_MACROS) add_executable(FoundationMacros) target_link_libraries(FoundationMacros PUBLIC SwiftSyntax::SwiftCompilerPlugin) +else() + add_library(FoundationMacros SHARED) + target_compile_definitions(FoundationMacros PRIVATE FOUNDATION_MACROS_LIBRARY) endif() # Parse the module as a library, even if it's an executable, because it uses an `@main` type to define its entry point. @@ -90,8 +93,6 @@ set_target_properties(FoundationMacros PROPERTIES INSTALL_RPATH "$ORIGIN/../../../swift/${SWIFT_SYSTEM_NAME}:$ORIGIN/.." INSTALL_REMOVE_ENVIRONMENT_RPATH ON) -if(NOT FoundationMacros_BuildLocalExecutable) - install(TARGETS FoundationMacros - LIBRARY DESTINATION lib/swift/host/plugins - RUNTIME DESTINATION bin) -endif() +install(TARGETS FoundationMacros + LIBRARY DESTINATION lib/swift/host/plugins + RUNTIME DESTINATION bin) diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt index 996788612..2c498378e 100644 --- a/cmake/modules/CMakeLists.txt +++ b/cmake/modules/CMakeLists.txt @@ -12,6 +12,7 @@ ## ##===----------------------------------------------------------------------===## +set(SWIFT_FOUNDATION_BUILD_MACROS_FILE ${CMAKE_CURRENT_BINARY_DIR}/FoundationBuildMacros.cmake) set(SWIFT_FOUNDATION_EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/SwiftFoundationExports.cmake) set(SWIFT_FOUNDATION_ICU_EXPORTS_FILE ${SwiftFoundationICU_BINARY_DIR}/cmake/modules/SwiftFoundationICUExports.cmake) set(SWIFT_COLLECTIONS_EXPORTS_FILE ${SwiftCollections_BINARY_DIR}/cmake/modules/SwiftCollectionsExports.cmake) diff --git a/cmake/modules/SwiftFoundationConfig.cmake.in b/cmake/modules/SwiftFoundationConfig.cmake.in index 1692f34ca..ad5bff33d 100644 --- a/cmake/modules/SwiftFoundationConfig.cmake.in +++ b/cmake/modules/SwiftFoundationConfig.cmake.in @@ -13,6 +13,7 @@ ##===----------------------------------------------------------------------===## if(NOT TARGET SwiftFoundation) + include(@SWIFT_FOUNDATION_BUILD_MACROS_FILE@) include(@SWIFT_FOUNDATION_ICU_EXPORTS_FILE@) include(@SWIFT_COLLECTIONS_EXPORTS_FILE@) include(@SWIFT_FOUNDATION_EXPORTS_FILE@)