diff --git a/CMakeLists.txt b/CMakeLists.txt index edb6cf06f9..058fb31156 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,18 +93,22 @@ if(NOT SwiftFoundation_MODULE_TRIPLE) endif() # System dependencies -find_package(dispatch CONFIG) -if(NOT dispatch_FOUND) - if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android") - set(DEFAULT_DISPATCH_INCLUDE_PATH "/usr/lib/swift") - elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set(DEFAULT_DISPATCH_INCLUDE_PATH "$ENV{SDKROOT}usr/include") + +# We know libdispatch is always unavailable on WASI +if(NOT CMAKE_SYSTEM_NAME STREQUAL WASI) + find_package(dispatch CONFIG) + if(NOT dispatch_FOUND) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android") + set(DEFAULT_DISPATCH_INCLUDE_PATH "/usr/lib/swift") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(DEFAULT_DISPATCH_INCLUDE_PATH "$ENV{SDKROOT}usr/include") + endif() + set(DISPATCH_INCLUDE_PATH "${DEFAULT_DISPATCH_INCLUDE_PATH}" CACHE STRING "A path to where you can find libdispatch headers") + message("-- dispatch_DIR not found, using dispatch from SDK at ${DISPATCH_INCLUDE_PATH}") + list(APPEND _Foundation_common_build_flags + "-I${DISPATCH_INCLUDE_PATH}" + "-I${DISPATCH_INCLUDE_PATH}/Block") endif() - set(DISPATCH_INCLUDE_PATH "${DEFAULT_DISPATCH_INCLUDE_PATH}" CACHE STRING "A path to where you can find libdispatch headers") - message("-- dispatch_DIR not found, using dispatch from SDK at ${DISPATCH_INCLUDE_PATH}") - list(APPEND _Foundation_common_build_flags - "-I${DISPATCH_INCLUDE_PATH}" - "-I${DISPATCH_INCLUDE_PATH}/Block") endif() find_package(LibXml2 REQUIRED) find_package(CURL REQUIRED) @@ -113,7 +117,6 @@ find_package(CURL REQUIRED) list(APPEND _Foundation_common_build_flags "-DDEPLOYMENT_RUNTIME_SWIFT" "-DCF_BUILDING_CF" - "-DDEPLOYMENT_ENABLE_LIBDISPATCH" "-DHAVE_STRUCT_TIMESPEC" "-Wno-shorten-64-to-32" "-Wno-deprecated-declarations" @@ -126,16 +129,10 @@ list(APPEND _Foundation_common_build_flags "-Wno-switch" "-fblocks") -if(CMAKE_SYSTEM_NAME STREQUAL "WASI") - list(APPEND _Foundation_common_build_flags - "-D_WASI_EMULATED_SIGNAL" - "-DHAVE_STRLCPY" - "-DHAVE_STRLCAT" - ) -else() - list(APPEND _Foundation_common_build_flags - "-DSWIFT_CORELIBS_FOUNDATION_HAS_THREADS" - ) +if(NOT CMAKE_SYSTEM_NAME STREQUAL WASI) + list(APPEND _Foundation_common_build_flags + "-DDEPLOYMENT_ENABLE_LIBDISPATCH" + "-DSWIFT_CORELIBS_FOUNDATION_HAS_THREADS") endif() if(NOT "${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC") @@ -168,16 +165,17 @@ list(APPEND _Foundation_swift_build_flags "-Xfrontend" "-require-explicit-sendable") -if(CMAKE_SYSTEM_NAME STREQUAL "WASI") - list(APPEND _Foundation_swift_build_flags - "-D_WASI_EMULATED_SIGNAL" - "-DHAVE_STRLCPY" - "-DHAVE_STRLCAT" - ) +if(CMAKE_SYSTEM_NAME STREQUAL WASI) + # Enable wasi-libc emulation features + set(WASI_EMULATION_DEFS _WASI_EMULATED_MMAN _WASI_EMULATED_SIGNAL _WASI_EMULATED_PROCESS_CLOCKS) + foreach(def ${WASI_EMULATION_DEFS}) + list(APPEND _Foundation_swift_build_flags "SHELL:-Xcc -D${def}") + list(APPEND _Foundation_common_build_flags "-D${def}") + endforeach() else() - list(APPEND _Foundation_swift_build_flags - "-DSWIFT_CORELIBS_FOUNDATION_HAS_THREADS" - ) + # Assume we have threads on other platforms + list(APPEND _Foundation_swift_build_flags + "-DSWIFT_CORELIBS_FOUNDATION_HAS_THREADS") endif() if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android") diff --git a/Package.swift b/Package.swift index 1477aefd00..dc86631a79 100644 --- a/Package.swift +++ b/Package.swift @@ -39,14 +39,12 @@ let coreFoundationBuildSettings: [CSetting] = [ .headerSearchPath("internalInclude"), .define("DEBUG", .when(configuration: .debug)), .define("CF_BUILDING_CF"), - .define("DEPLOYMENT_ENABLE_LIBDISPATCH"), + .define("DEPLOYMENT_ENABLE_LIBDISPATCH", .when(platforms: platformsWithThreads)), .define("DEPLOYMENT_RUNTIME_SWIFT"), .define("HAVE_STRUCT_TIMESPEC"), .define("SWIFT_CORELIBS_FOUNDATION_HAS_THREADS", .when(platforms: platformsWithThreads)), .define("_GNU_SOURCE", .when(platforms: [.linux, .android])), .define("_WASI_EMULATED_SIGNAL", .when(platforms: [.wasi])), - .define("HAVE_STRLCPY", .when(platforms: [.wasi])), - .define("HAVE_STRLCAT", .when(platforms: [.wasi])), .unsafeFlags([ "-Wno-shorten-64-to-32", "-Wno-deprecated-declarations", @@ -78,8 +76,6 @@ let interfaceBuildSettings: [CSetting] = [ .define("SWIFT_CORELIBS_FOUNDATION_HAS_THREADS", .when(platforms: platformsWithThreads)), .define("_GNU_SOURCE", .when(platforms: [.linux, .android])), .define("_WASI_EMULATED_SIGNAL", .when(platforms: [.wasi])), - .define("HAVE_STRLCPY", .when(platforms: [.wasi])), - .define("HAVE_STRLCAT", .when(platforms: [.wasi])), .unsafeFlags([ "-Wno-shorten-64-to-32", "-Wno-deprecated-declarations", @@ -161,7 +157,8 @@ let package = Package( .product(name: "FoundationEssentials", package: "swift-foundation"), "Foundation", "CoreFoundation", - "_CFXMLInterface" + "_CFXMLInterface", + .target(name: "BlocksRuntime", condition: .when(platforms: [.wasi])), ], path: "Sources/FoundationXML", exclude: [ @@ -187,6 +184,7 @@ let package = Package( name: "CoreFoundation", dependencies: [ .product(name: "_FoundationICU", package: "swift-foundation-icu"), + .target(name: "BlocksRuntime", condition: .when(platforms: [.wasi])), ], path: "Sources/CoreFoundation", exclude: [ @@ -195,6 +193,17 @@ let package = Package( ], cSettings: coreFoundationBuildSettings ), + .target( + name: "BlocksRuntime", + path: "Sources/CoreFoundation/BlockRuntime", + exclude: [ + "CMakeLists.txt" + ], + cSettings: [ + // For CFTargetConditionals.h + .headerSearchPath("../include"), + ] + ), .target( name: "_CFXMLInterface", dependencies: [ diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt index 0ee266a4bc..29b9244065 100644 --- a/Sources/CMakeLists.txt +++ b/Sources/CMakeLists.txt @@ -14,10 +14,14 @@ add_subdirectory(CoreFoundation) add_subdirectory(_CFXMLInterface) -add_subdirectory(_CFURLSessionInterface) +if(NOT CMAKE_SYSTEM_NAME STREQUAL "WASI") + add_subdirectory(_CFURLSessionInterface) +endif() add_subdirectory(Foundation) add_subdirectory(FoundationXML) -add_subdirectory(FoundationNetworking) +if(NOT CMAKE_SYSTEM_NAME STREQUAL "WASI") + add_subdirectory(FoundationNetworking) +endif() if(FOUNDATION_BUILD_TOOLS) add_subdirectory(plutil) endif() diff --git a/Sources/CoreFoundation/BlockRuntime/CMakeLists.txt b/Sources/CoreFoundation/BlockRuntime/CMakeLists.txt new file mode 100644 index 0000000000..47779784e7 --- /dev/null +++ b/Sources/CoreFoundation/BlockRuntime/CMakeLists.txt @@ -0,0 +1,29 @@ +##===----------------------------------------------------------------------===## +## +## This source file is part of the Swift open source project +## +## Copyright (c) 2024 Apple Inc. and the Swift project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.md for the list of Swift project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## + +# Build the vendored version of the BlocksRuntime library, which is used by +# platforms that don't support libdispatch. + +# Build the BlocksRuntime as an object library, shipped as a part +# of libCoreFoundation. +add_library(BlocksRuntime OBJECT + data.c + runtime.c) + +target_include_directories(BlocksRuntime PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + # For CFTargetConditionals.h + ${CMAKE_CURRENT_SOURCE_DIR}/../include) + +set_property(GLOBAL APPEND PROPERTY Foundation_EXPORTS BlocksRuntime) diff --git a/Sources/CoreFoundation/CFBundle.c b/Sources/CoreFoundation/CFBundle.c index 05afe9888e..607c7bd925 100644 --- a/Sources/CoreFoundation/CFBundle.c +++ b/Sources/CoreFoundation/CFBundle.c @@ -600,7 +600,7 @@ CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID) { #if TARGET_OS_WASI hint = NULL; #else - hint = __builtin_frame_address(0); + hint = __builtin_return_address(0); #endif return _CFBundleGetBundleWithIdentifier(bundleID, hint); } diff --git a/Sources/CoreFoundation/CFString.c b/Sources/CoreFoundation/CFString.c index 94a6c86d15..f8899e1589 100644 --- a/Sources/CoreFoundation/CFString.c +++ b/Sources/CoreFoundation/CFString.c @@ -35,7 +35,7 @@ #include #include #include -#if TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD +#if TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WASI #include #endif #if TARGET_OS_WASI diff --git a/Sources/CoreFoundation/CMakeLists.txt b/Sources/CoreFoundation/CMakeLists.txt index e366005f72..71e7c2f00d 100644 --- a/Sources/CoreFoundation/CMakeLists.txt +++ b/Sources/CoreFoundation/CMakeLists.txt @@ -118,6 +118,13 @@ target_link_libraries(CoreFoundation _FoundationICU dispatch) +if(CMAKE_SYSTEM_NAME STREQUAL WASI) + # On WASI, we use vendored BlocksRuntime instead of the one from libdispatch + add_subdirectory(BlockRuntime) + # Add BlocksRuntime object library to CoreFoundation static archive + target_link_libraries(CoreFoundation PRIVATE BlocksRuntime) +endif() + set_property(GLOBAL APPEND PROPERTY Foundation_EXPORTS CoreFoundation) # Copy Headers to known directory for direct client (XCTest) test builds diff --git a/Sources/CoreFoundation/include/CoreFoundation.h b/Sources/CoreFoundation/include/CoreFoundation.h index a66e7e614d..64313f0b9f 100644 --- a/Sources/CoreFoundation/include/CoreFoundation.h +++ b/Sources/CoreFoundation/include/CoreFoundation.h @@ -58,9 +58,7 @@ #include "CFLocale.h" #include "CFNumber.h" #include "CFNumberFormatter.h" -#if !TARGET_OS_WASI #include "CFPreferences.h" -#endif #include "CFPropertyList.h" #include "CFSet.h" #include "CFString.h" @@ -76,13 +74,17 @@ #include "ForSwiftFoundationOnly.h" -#if TARGET_OS_OSX || TARGET_OS_IPHONE || TARGET_OS_WIN32 || TARGET_OS_LINUX +#if TARGET_OS_OSX || TARGET_OS_IPHONE || TARGET_OS_WIN32 || TARGET_OS_LINUX || TARGET_OS_WASI +# if !TARGET_OS_WASI #include "CFMessagePort.h" #include "CFPlugIn.h" +# endif #include "CFRunLoop.h" #include "CFStream.h" +# if !TARGET_OS_WASI #include "CFSocket.h" #include "CFMachPort.h" +# endif #include "CFAttributedString.h" #include "CFNotificationCenter.h" diff --git a/Sources/CoreFoundation/internalInclude/CoreFoundation_Prefix.h b/Sources/CoreFoundation/internalInclude/CoreFoundation_Prefix.h index 9ef8f64a6c..dea3b57537 100644 --- a/Sources/CoreFoundation/internalInclude/CoreFoundation_Prefix.h +++ b/Sources/CoreFoundation/internalInclude/CoreFoundation_Prefix.h @@ -109,6 +109,11 @@ typedef char * Class; #include #endif +#if TARGET_OS_WASI +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#endif + #if TARGET_OS_WIN32 #define BOOL WINDOWS_BOOL diff --git a/Sources/_CFXMLInterface/CMakeLists.txt b/Sources/_CFXMLInterface/CMakeLists.txt index d6e63a3f59..9ca0c27900 100644 --- a/Sources/_CFXMLInterface/CMakeLists.txt +++ b/Sources/_CFXMLInterface/CMakeLists.txt @@ -20,7 +20,7 @@ target_include_directories(_CFXMLInterface ../CoreFoundation/include PRIVATE ../CoreFoundation/internalInclude - /usr/include/libxml2/) + ${LIBXML2_INCLUDE_DIR}) target_compile_options(_CFXMLInterface INTERFACE "$<$:SHELL:-Xcc -fmodule-map-file=${CMAKE_CURRENT_SOURCE_DIR}/../CoreFoundation/include/module.modulemap>" @@ -33,6 +33,10 @@ target_link_libraries(_CFXMLInterface PRIVATE dispatch LibXml2::LibXml2) +if(CMAKE_SYSTEM_NAME STREQUAL WASI) + target_link_libraries(_CFXMLInterface PRIVATE BlocksRuntime) +endif() + if(NOT BUILD_SHARED_LIBS) set_property(GLOBAL APPEND PROPERTY Foundation_EXPORTS _CFXMLInterface) install(TARGETS _CFXMLInterface