diff --git a/.github/workflows/compatibility_tests.yml b/.github/workflows/compatibility_tests.yml index 8611b8c6..37dd4cd7 100644 --- a/.github/workflows/compatibility_tests.yml +++ b/.github/workflows/compatibility_tests.yml @@ -42,6 +42,7 @@ jobs: - name: Run tests against Apple's AttributeGraph on macOS via Xcode run: | xcodebuild test \ + -workspace .swiftpm/xcode/package.xcworkspace \ -scheme OpenAttributeGraph-Package \ -sdk macosx \ -destination "platform=macOS" \ diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 2397b7e2..96e1d1f4 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -41,6 +41,7 @@ jobs: - name: Build in debug mode on iOS run: | xcodebuild build \ + -workspace .swiftpm/xcode/package.xcworkspace \ -scheme OpenAttributeGraph-Package \ -configuration Debug \ -destination "platform=iOS Simulator,OS=${{ matrix.ios-version }},name=${{ matrix.ios-simulator-name }}" \ @@ -51,6 +52,7 @@ jobs: - name: Build and run tests in debug mode with coverage on iOS Simulator run: | xcodebuild test \ + -workspace .swiftpm/xcode/package.xcworkspace \ -scheme OpenAttributeGraph-Package \ -configuration Debug \ -destination "platform=iOS Simulator,OS=${{ matrix.ios-version }},name=${{ matrix.ios-simulator-name }}" \ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..aee171e5 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,89 @@ +name: Release + +on: + push: + tags: + - '[0-9]+.[0-9]+.[0-9]+' + +jobs: + release: + name: Build and Publish Release + runs-on: macos-15 + permissions: + contents: write + env: + GH_TOKEN: ${{ github.token }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup Xcode + uses: OpenSwiftUIProject/OpenSwiftUI/.github/actions/setup-xcode@main + with: + xcode-version: "16.4" + - name: Checkout Swift headers + uses: ./.github/actions/checkout-swift-headers + - name: Build XCFramework + run: ./Scripts/build_xcframework.sh + - name: Compute Checksum + id: checksum + run: | + echo "checksum=$(swift package compute-checksum .build/Xcode/Frameworks/OpenAttributeGraph.xcframework.zip)" >> $GITHUB_OUTPUT + - name: Collect Build Info + id: build_info + run: | + echo "xcode_version=$(xcodebuild -version | head -1)" >> $GITHUB_OUTPUT + echo "swift_version=$(swift --version 2>&1 | head -1)" >> $GITHUB_OUTPUT + - name: Generate Release Notes + id: release_notes + run: | + TAG_NAME="${GITHUB_REF#refs/tags/}" + # Find the previous tag + PREV_TAG=$(git tag --sort=-v:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sed -n '2p') + REPO="${GITHUB_REPOSITORY}" + DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${TAG_NAME}/OpenAttributeGraph.xcframework.zip" + + { + echo 'body<> "$GITHUB_OUTPUT" + - name: Create Release + uses: ncipollo/release-action@v1 + with: + body: ${{ steps.release_notes.outputs.body }} + allowUpdates: true + artifacts: ".build/Xcode/Frameworks/OpenAttributeGraph.xcframework.zip" + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/xcframework.yml b/.github/workflows/xcframework.yml new file mode 100644 index 00000000..cb15746f --- /dev/null +++ b/.github/workflows/xcframework.yml @@ -0,0 +1,34 @@ +name: XCFramework + +on: + push: + tags: + - '[0-9]+.[0-9]+.[0-9]+' + workflow_dispatch: + +jobs: + build_xcframework: + name: Build XCFramework + strategy: + fail-fast: false + matrix: + os: [macos-15] + xcode-version: ["16.4"] # Swift 6.1.2 + runs-on: ${{ matrix.os }} + env: + GH_TOKEN: ${{ github.token }} + steps: + - uses: actions/checkout@v4 + - name: Setup Xcode + uses: OpenSwiftUIProject/OpenSwiftUI/.github/actions/setup-xcode@main + with: + xcode-version: ${{ matrix.xcode-version }} + - name: Checkout Swift headers + uses: ./.github/actions/checkout-swift-headers + - name: Build XCFramework + run: ./Scripts/build_xcframework.sh + - name: Upload XCFramework + uses: actions/upload-artifact@v4 + with: + name: OpenAttributeGraph.xcframework.zip + path: .build/Xcode/Frameworks/OpenAttributeGraph.xcframework.zip diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Configs/Common.xcconfig b/Configs/Common.xcconfig new file mode 100644 index 00000000..04e2fde1 --- /dev/null +++ b/Configs/Common.xcconfig @@ -0,0 +1,44 @@ +// Common.xcconfig +// Shared build settings for OpenAttributeGraph + +// MARK: - Deployment Targets + +MACOSX_DEPLOYMENT_TARGET = 15.0 +IPHONEOS_DEPLOYMENT_TARGET = 18.0 +XROS_DEPLOYMENT_TARGET = 2.0 + +// MARK: - Platform + +SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx xros xrsimulator +ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES +TARGETED_DEVICE_FAMILY = 1,2,7 +SDKROOT = auto + +// MARK: - C/C++ Language + +GCC_C_LANGUAGE_STANDARD = gnu17 +CLANG_CXX_LANGUAGE_STANDARD = gnu++20 +CLANG_ENABLE_MODULES = YES + +// MARK: - C/C++ Flags + +// -ftyped-memory-operations: Rewrite malloc() to malloc_type_malloc() for type-isolated allocation buckets (xzone malloc) +// -ftyped-cxx-new-delete: Rewrite operator new/delete to typed variants +OTHER_CFLAGS = $(inherited) -ftyped-memory-operations +OTHER_CPLUSPLUSFLAGS = $(inherited) -ftyped-memory-operations -ftyped-cxx-new-delete + +// MARK: - C/C++ Preprocessor + +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) OPENATTRIBUTEGRAPH=1 +GCC_PREPROCESSOR_DEFINITIONS[config=Debug] = $(inherited) OPENATTRIBUTEGRAPH=1 DEBUG=1 + +// MARK: - Header Search Paths + +SYSTEM_HEADER_SEARCH_PATHS = $(inherited) Checkouts/swift/include Checkouts/swift/stdlib/include Checkouts/swift/stdlib/public/SwiftShims + +// MARK: - Swift + +SWIFT_VERSION = 5.0 +OTHER_SWIFT_FLAGS = $(inherited) -enable-experimental-feature Extern -enable-upcoming-feature InternalImportsByDefault +SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) OPENATTRIBUTEGRAPH OPENATTRIBUTEGRAPH_RELEASE_2024 OPENATTRIBUTEGRAPH_SUPPORT_2021_API OPENATTRIBUTEGRAPH_SUPPORT_2022_API OPENATTRIBUTEGRAPH_SUPPORT_2023_API OPENATTRIBUTEGRAPH_SUPPORT_2024_API +SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Debug] = $(inherited) DEBUG OPENATTRIBUTEGRAPH OPENATTRIBUTEGRAPH_RELEASE_2024 OPENATTRIBUTEGRAPH_SUPPORT_2021_API OPENATTRIBUTEGRAPH_SUPPORT_2022_API OPENATTRIBUTEGRAPH_SUPPORT_2023_API OPENATTRIBUTEGRAPH_SUPPORT_2024_API diff --git a/Configs/OpenAttributeGraph.xcconfig b/Configs/OpenAttributeGraph.xcconfig new file mode 100644 index 00000000..8b43e769 --- /dev/null +++ b/Configs/OpenAttributeGraph.xcconfig @@ -0,0 +1,48 @@ +// OpenAttributeGraph.xcconfig +// Framework target build settings + +#include "Common.xcconfig" + +// MARK: - Product + +PRODUCT_BUNDLE_IDENTIFIER = org.OpenSwiftUIProject.OpenAttributeGraph +PRODUCT_NAME = $(TARGET_NAME:c99extidentifier) + +// MARK: - Module +// NOTE: The SPM module.modulemap defines a non-framework module (OpenAttributeGraphCxx), +// which is not suitable for Xcode framework builds. The build_xcframework.sh +// post-processing injects the correct framework module map for distribution. + +// MARK: - Header Search Paths + +HEADER_SEARCH_PATHS = $(inherited) Sources/Platform/include Sources/Utilities/include Sources/OpenAttributeGraphCxx/include +USER_HEADER_SEARCH_PATHS = $(inherited) Sources/OpenAttributeGraphCxx +USE_HEADERMAP = NO + +// MARK: - Swift + +SWIFT_INCLUDE_PATHS = $(inherited) Sources/OpenAttributeGraphCxx/include +SWIFT_INSTALL_MODULE = YES +SWIFT_INSTALL_OBJC_HEADER = NO +OTHER_SWIFT_FLAGS = $(inherited) -no-verify-emitted-module-interface + +// MARK: - Library Evolution + +BUILD_LIBRARY_FOR_DISTRIBUTION = YES +SKIP_INSTALL = NO + +// MARK: - Framework + +GENERATE_INFOPLIST_FILE = YES +CURRENT_PROJECT_VERSION = 1 +MARKETING_VERSION = 1.0 +// OAGVersion.c defines OpenAttributeGraphVersionNumber/String manually, +// so disable Xcode's auto-generated version object to avoid duplicate symbols. +// VERSIONING_SYSTEM = apple-generic +DYLIB_COMPATIBILITY_VERSION = 1 +DYLIB_CURRENT_VERSION = 1 +DYLIB_INSTALL_NAME_BASE = @rpath +INSTALL_PATH = $(LOCAL_LIBRARY_DIR)/Frameworks +// Module verifier disabled: public headers use double-quoted includes and +// reference internal paths not available in the framework context. +ENABLE_MODULE_VERIFIER = NO diff --git a/Configs/OpenAttributeGraphTests.xcconfig b/Configs/OpenAttributeGraphTests.xcconfig new file mode 100644 index 00000000..bb4b3321 --- /dev/null +++ b/Configs/OpenAttributeGraphTests.xcconfig @@ -0,0 +1,6 @@ +// OpenAttributeGraphTests.xcconfig +// Test target build settings + +#include "Common.xcconfig" + +PRODUCT_BUNDLE_IDENTIFIER = org.OpenSwiftUIProject.OpenAttributeGraphTests diff --git a/OpenAttributeGraph.xcodeproj/project.pbxproj b/OpenAttributeGraph.xcodeproj/project.pbxproj new file mode 100644 index 00000000..4fab947a --- /dev/null +++ b/OpenAttributeGraph.xcodeproj/project.pbxproj @@ -0,0 +1,343 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + OAG0000010000000000000001 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = OAG0000020000000000000001 /* libz.tbd */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + OAG0000020000000000000001 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; + OAG0000030000000000000001 /* OpenAttributeGraph.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OpenAttributeGraph.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + OAG00000C0000000000000001 /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; + OAG00000C0000000000000002 /* OpenAttributeGraph.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = OpenAttributeGraph.xcconfig; sourceTree = ""; }; + OAG00000C0000000000000003 /* OpenAttributeGraphTests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = OpenAttributeGraphTests.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 277F10582F4EF9460061C27D /* Exceptions for "OpenAttributeGraphCxx" folder in "OpenAttributeGraph" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + include/OpenAttributeGraphCxx/Vector/vector.tpp, + include/SwiftBridging/README.md, + ); + target = OAG0000080000000000000001 /* OpenAttributeGraph */; + }; + OAG00000D0000000000000001 /* Exceptions for "Platform" folder in "OpenAttributeGraph" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + README.md, + ); + target = OAG0000080000000000000001 /* OpenAttributeGraph */; + }; + OAG00000D0000000000000002 /* Exceptions for "Utilities" folder in "OpenAttributeGraph" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + include/SwiftBridging/README.md, + README.md, + ); + target = OAG0000080000000000000001 /* OpenAttributeGraph */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + OAG0000040000000000000001 /* Platform */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + OAG00000D0000000000000001 /* Exceptions for "Platform" folder in "OpenAttributeGraph" target */, + ); + name = Platform; + path = Sources/Platform; + sourceTree = ""; + }; + OAG0000040000000000000002 /* Utilities */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + OAG00000D0000000000000002 /* Exceptions for "Utilities" folder in "OpenAttributeGraph" target */, + ); + name = Utilities; + path = Sources/Utilities; + sourceTree = ""; + }; + OAG0000040000000000000003 /* OpenAttributeGraphCxx */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 277F10582F4EF9460061C27D /* Exceptions for "OpenAttributeGraphCxx" folder in "OpenAttributeGraph" target */, + ); + name = OpenAttributeGraphCxx; + path = Sources/OpenAttributeGraphCxx; + sourceTree = ""; + }; + OAG0000040000000000000004 /* OpenAttributeGraph */ = { + isa = PBXFileSystemSynchronizedRootGroup; + name = OpenAttributeGraph; + path = Sources/OpenAttributeGraph; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + OAG0000050000000000000001 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + OAG0000010000000000000001 /* libz.tbd in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + OAG0000060000000000000001 = { + isa = PBXGroup; + children = ( + OAG0000040000000000000001 /* Platform */, + OAG0000040000000000000002 /* Utilities */, + OAG0000040000000000000003 /* OpenAttributeGraphCxx */, + OAG0000040000000000000004 /* OpenAttributeGraph */, + OAG00000B0000000000000001 /* Configs */, + OAG0000060000000000000003 /* Frameworks */, + OAG0000060000000000000002 /* Products */, + ); + sourceTree = ""; + }; + OAG0000060000000000000002 /* Products */ = { + isa = PBXGroup; + children = ( + OAG0000030000000000000001 /* OpenAttributeGraph.framework */, + ); + name = Products; + sourceTree = ""; + }; + OAG0000060000000000000003 /* Frameworks */ = { + isa = PBXGroup; + children = ( + OAG0000020000000000000001 /* libz.tbd */, + ); + name = Frameworks; + sourceTree = ""; + }; + OAG00000B0000000000000001 /* Configs */ = { + isa = PBXGroup; + children = ( + OAG00000C0000000000000001 /* Common.xcconfig */, + OAG00000C0000000000000002 /* OpenAttributeGraph.xcconfig */, + OAG00000C0000000000000003 /* OpenAttributeGraphTests.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + OAG0000070000000000000001 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + OAG0000080000000000000001 /* OpenAttributeGraph */ = { + isa = PBXNativeTarget; + buildConfigurationList = OAG000009000000000000000A /* Build configuration list for PBXNativeTarget "OpenAttributeGraph" */; + buildPhases = ( + OAG0000070000000000000001 /* Headers */, + OAG00000A0000000000000001 /* Process Headers */, + OAG0000050000000000000002 /* Sources */, + OAG0000050000000000000001 /* Frameworks */, + OAG0000050000000000000003 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + OAG0000040000000000000001 /* Platform */, + OAG0000040000000000000002 /* Utilities */, + OAG0000040000000000000003 /* OpenAttributeGraphCxx */, + OAG0000040000000000000004 /* OpenAttributeGraph */, + ); + name = OpenAttributeGraph; + packageProductDependencies = ( + ); + productName = OpenAttributeGraph; + productReference = OAG0000030000000000000001 /* OpenAttributeGraph.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + OAG0000060000000000000000 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastUpgradeCheck = 1640; + TargetAttributes = { + OAG0000080000000000000001 = { + CreatedOnToolsVersion = 16.4; + }; + }; + }; + buildConfigurationList = OAG0000090000000000000001 /* Build configuration list for PBXProject "OpenAttributeGraph" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = OAG0000060000000000000001; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = OAG0000060000000000000002 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + OAG0000080000000000000001 /* OpenAttributeGraph */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + OAG0000050000000000000003 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + OAG00000A0000000000000001 /* Process Headers */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "$(SRCROOT)/Scripts/Xcode/process_headers_inputs.xcfilelist", + ); + inputPaths = ( + "$(SRCROOT)/Scripts/Xcode/process_headers.sh", + ); + name = "Process Headers"; + outputFileListPaths = ( + "$(SRCROOT)/Scripts/Xcode/process_headers_outputs.xcfilelist", + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nScripts/Xcode/process_headers.sh\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + OAG0000050000000000000002 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + OAG0000090000000000000002 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = OAG00000C0000000000000001 /* Common.xcconfig */; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + OAG0000090000000000000003 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = OAG00000C0000000000000001 /* Common.xcconfig */; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_NO_COMMON_BLOCKS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SWIFT_COMPILATION_MODE = wholemodule; + }; + name = Release; + }; + OAG0000090000000000000004 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = OAG00000C0000000000000002 /* OpenAttributeGraph.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + LD_RUNPATH_SEARCH_PATHS = ( + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + }; + name = Debug; + }; + OAG0000090000000000000005 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = OAG00000C0000000000000002 /* OpenAttributeGraph.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + LD_RUNPATH_SEARCH_PATHS = ( + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + OAG0000090000000000000001 /* Build configuration list for PBXProject "OpenAttributeGraph" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + OAG0000090000000000000002 /* Debug */, + OAG0000090000000000000003 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + OAG000009000000000000000A /* Build configuration list for PBXNativeTarget "OpenAttributeGraph" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + OAG0000090000000000000004 /* Debug */, + OAG0000090000000000000005 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = OAG0000060000000000000000 /* Project object */; +} diff --git a/OpenAttributeGraph.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/OpenAttributeGraph.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/OpenAttributeGraph.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Scripts/Xcode/process_headers.sh b/Scripts/Xcode/process_headers.sh new file mode 100755 index 00000000..56fbb51f --- /dev/null +++ b/Scripts/Xcode/process_headers.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +set -e + +# Post-process headers: replace #include with #include +# Uses Xcode's SCRIPT_INPUT_FILE_LIST_* and SCRIPT_OUTPUT_FILE_LIST_* for sandbox compatibility + +if [ "$SCRIPT_INPUT_FILE_LIST_COUNT" -eq 0 ]; then + echo "error: No input file list specified" + exit 1 +fi + +if [ "$SCRIPT_OUTPUT_FILE_LIST_COUNT" -eq 0 ]; then + echo "error: No output file list specified" + exit 1 +fi + +count=0 + +# Process input and output file lists line by line +while IFS= read -r input_file <&3 && IFS= read -r output_file <&4; do + # Skip empty lines (skip both to keep lists in sync) + [ -z "$input_file" ] && continue + [ -z "$output_file" ] && continue + + # Create output directory if needed + mkdir -p "$(dirname "$output_file")" + + # Replace #include with #include + sed 's|#include "$output_file" + + echo "Processed: $(basename "$input_file") -> $(basename "$output_file")" + count=$((count + 1)) +done 3< "$SCRIPT_INPUT_FILE_LIST_0" 4< "$SCRIPT_OUTPUT_FILE_LIST_0" + +echo "Processed $count headers" diff --git a/Scripts/Xcode/process_headers_inputs.xcfilelist b/Scripts/Xcode/process_headers_inputs.xcfilelist new file mode 100644 index 00000000..b3722d05 --- /dev/null +++ b/Scripts/Xcode/process_headers_inputs.xcfilelist @@ -0,0 +1,32 @@ +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGAttribute.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGAttributeFlags.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGAttributeInfo.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGAttributeType.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGAttributeTypeFlags.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGBase.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGCachedValueOptions.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGChangedValueFlags.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGClosure.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGComparison.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGDebugServer.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGGraph.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGGraphContext.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGGraphCounterQueryType.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGGraphDescription.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGGraphTracing.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGInputOptions.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGSearchOptions.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGSubgraph.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGSwiftSupport.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGTargetConditionals.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGTrace.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGTupleType.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGTypeID.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGUniqueID.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGValue.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGValueOptions.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGValueState.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGVersion.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGWeakAttribute.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OAGWeakValue.h +$(SRCROOT)/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph/OpenAttributeGraph.h diff --git a/Scripts/Xcode/process_headers_outputs.xcfilelist b/Scripts/Xcode/process_headers_outputs.xcfilelist new file mode 100644 index 00000000..c607dad9 --- /dev/null +++ b/Scripts/Xcode/process_headers_outputs.xcfilelist @@ -0,0 +1,32 @@ +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGAttribute.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGAttributeFlags.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGAttributeInfo.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGAttributeType.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGAttributeTypeFlags.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGBase.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGCachedValueOptions.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGChangedValueFlags.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGClosure.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGComparison.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGDebugServer.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGGraph.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGGraphContext.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGGraphCounterQueryType.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGGraphDescription.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGGraphTracing.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGInputOptions.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGSearchOptions.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGSubgraph.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGSwiftSupport.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGTargetConditionals.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGTrace.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGTupleType.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGTypeID.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGUniqueID.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGValue.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGValueOptions.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGValueState.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGVersion.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGWeakAttribute.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OAGWeakValue.h +$(BUILT_PRODUCTS_DIR)/$(PUBLIC_HEADERS_FOLDER_PATH)/OpenAttributeGraph.h diff --git a/Scripts/build_xcframework.sh b/Scripts/build_xcframework.sh index b34aa88e..a2d87d5f 100755 --- a/Scripts/build_xcframework.sh +++ b/Scripts/build_xcframework.sh @@ -1,19 +1,16 @@ #!/bin/bash - -# Script modified from https://docs.emergetools.com/docs/analyzing-a-spm-framework-ios set -e -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd -P)" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd -P)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" -PROJECT_BUILD_DIR="${PROJECT_BUILD_DIR:-"${PROJECT_ROOT}/build"}" -XCODEBUILD_BUILD_DIR="$PROJECT_BUILD_DIR/xcodebuild" -XCODEBUILD_DERIVED_DATA_PATH="$XCODEBUILD_BUILD_DIR/DerivedData" +BUILD_DIR="$PROJECT_ROOT/.build/Xcode" +SCHEME="OpenAttributeGraph" -# Copy and modify modulemap -mkdir -p "$PROJECT_BUILD_DIR" -cat > "$PROJECT_BUILD_DIR/module.modulemap" << 'EOF' +# Copy and modify modulemap for framework distribution +mkdir -p "$BUILD_DIR/Archives" "$BUILD_DIR/Frameworks" +cat > "$BUILD_DIR/module.modulemap" << 'EOF' framework module OpenAttributeGraph { umbrella header "OpenAttributeGraph.h" export * @@ -23,8 +20,6 @@ EOF # Parse arguments DEBUG_INFO=false -PACKAGE_NAME="" - while [[ $# -gt 0 ]]; do case $1 in --debug-info) @@ -32,106 +27,83 @@ while [[ $# -gt 0 ]]; do shift ;; *) - if [ -z "$PACKAGE_NAME" ]; then - PACKAGE_NAME="$1" - fi shift ;; esac done -if [ -z "$PACKAGE_NAME" ]; then - echo "No package name provided. Using the first scheme found in the Package.swift." - PACKAGE_NAME=$(xcodebuild -list | awk 'schemes && NF>0 { print $1; exit } /Schemes:$/ { schemes = 1 }') - echo "Using: $PACKAGE_NAME" -fi +echo "Building xcframework for $SCHEME (debug info: $DEBUG_INFO)" -echo "Building xcframework for package: $PACKAGE_NAME contains debug info: $DEBUG_INFO" - -build_framework() { - local sdk="$1" - local destination="$2" - local scheme="$3" - - local XCODEBUILD_ARCHIVE_PATH="./build/$scheme-$sdk.xcarchive" - - rm -rf "$XCODEBUILD_ARCHIVE_PATH" - - xcodebuild archive \ - -scheme $scheme \ - -archivePath $XCODEBUILD_ARCHIVE_PATH \ - -derivedDataPath "$XCODEBUILD_DERIVED_DATA_PATH" \ - -sdk "$sdk" \ - -destination "$destination" \ - BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ - INSTALL_PATH='Library/Frameworks' \ - OTHER_SWIFT_FLAGS=-no-verify-emitted-module-interface - - if [ "$sdk" = "macosx" ]; then - FRAMEWORK_MODULES_PATH="$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Versions/Current/Modules" - FRAMEWORK_HEADERS_PATH="$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Versions/Current/Headers" - mkdir -p "$FRAMEWORK_MODULES_PATH" - mkdir -p "$FRAMEWORK_HEADERS_PATH" - cp -r \ - "$XCODEBUILD_DERIVED_DATA_PATH/Build/Intermediates.noindex/ArchiveIntermediates/$scheme/BuildProductsPath/Release/$scheme.swiftmodule" \ - "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule" - # Replace OpenAttributeGraphCxx with OpenAttributeGraph in swiftinterface files - find "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule" -name "*.swiftinterface" -exec sed -i '' 's/OpenAttributeGraphCxx/OpenAttributeGraph/g' {} \; - cp -r \ - "$PROJECT_ROOT/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph"/* \ - "$FRAMEWORK_HEADERS_PATH/" 2>/dev/null || true - cp "$PROJECT_BUILD_DIR/module.modulemap" \ - "$FRAMEWORK_MODULES_PATH/module.modulemap" 2>/dev/null || true - rm -rf "$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Modules" - rm -rf "$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Headers" - ln -s Versions/Current/Modules "$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Modules" - ln -s Versions/Current/Headers "$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Headers" - else - FRAMEWORK_MODULES_PATH="$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Modules" - FRAMEWORK_HEADERS_PATH="$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Headers" - mkdir -p "$FRAMEWORK_MODULES_PATH" - mkdir -p "$FRAMEWORK_HEADERS_PATH" - cp -r \ - "$XCODEBUILD_DERIVED_DATA_PATH/Build/Intermediates.noindex/ArchiveIntermediates/$scheme/BuildProductsPath/Release-$sdk/$scheme.swiftmodule" \ - "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule" - # Replace OpenAttributeGraphCxx with OpenAttributeGraph in swiftinterface files - find "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule" -name "*.swiftinterface" -exec sed -i '' 's/OpenAttributeGraphCxx/OpenAttributeGraph/g' {} \; - cp -r \ - "$PROJECT_ROOT/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph"/* \ - "$FRAMEWORK_HEADERS_PATH/" 2>/dev/null || true - cp "$PROJECT_BUILD_DIR/module.modulemap" \ - "$FRAMEWORK_MODULES_PATH/module.modulemap" 2>/dev/null || true - fi - - # Delete private and package swiftinterface - rm -f "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule/*.package.swiftinterface" - rm -f "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule/*.private.swiftinterface" -} +# Archive for each platform using the xcodeproj +xcodebuild archive \ + -project "$PROJECT_ROOT/OpenAttributeGraph.xcodeproj" \ + -scheme "$SCHEME" \ + -destination "generic/platform=macOS" \ + -archivePath "$BUILD_DIR/Archives/$SCHEME-macOS.xcarchive" \ + ENABLE_USER_SCRIPT_SANDBOXING=NO -build_framework "iphonesimulator" "generic/platform=iOS Simulator" "$PACKAGE_NAME" -build_framework "iphoneos" "generic/platform=iOS" "$PACKAGE_NAME" -build_framework "macosx" "generic/platform=macOS" "$PACKAGE_NAME" +xcodebuild archive \ + -project "$PROJECT_ROOT/OpenAttributeGraph.xcodeproj" \ + -scheme "$SCHEME" \ + -destination "generic/platform=iOS" \ + -archivePath "$BUILD_DIR/Archives/$SCHEME-iOS.xcarchive" \ + ENABLE_USER_SCRIPT_SANDBOXING=NO -echo "Builds completed successfully." +xcodebuild archive \ + -project "$PROJECT_ROOT/OpenAttributeGraph.xcodeproj" \ + -scheme "$SCHEME" \ + -destination "generic/platform=iOS Simulator" \ + -archivePath "$BUILD_DIR/Archives/$SCHEME-iOS-Simulator.xcarchive" \ + ENABLE_USER_SCRIPT_SANDBOXING=NO -cd $PROJECT_BUILD_DIR +echo "Archives completed successfully." -rm -rf "$PACKAGE_NAME.xcframework" +# Create xcframework +rm -rf "$BUILD_DIR/Frameworks/$SCHEME.xcframework" if [ "$DEBUG_INFO" = true ]; then echo "Creating xcframework with debug symbols..." - xcodebuild -create-xcframework \ - -framework $PACKAGE_NAME-iphonesimulator.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ - -debug-symbols "$(realpath $PACKAGE_NAME-iphonesimulator.xcarchive/dSYMs/$PACKAGE_NAME.framework.dSYM)" \ - -framework $PACKAGE_NAME-iphoneos.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ - -debug-symbols "$(realpath $PACKAGE_NAME-iphoneos.xcarchive/dSYMs/$PACKAGE_NAME.framework.dSYM)" \ - -framework $PACKAGE_NAME-macosx.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ - -debug-symbols "$(realpath $PACKAGE_NAME-macosx.xcarchive/dSYMs/$PACKAGE_NAME.framework.dSYM)" \ - -output $PACKAGE_NAME.xcframework + xcodebuild -create-xcframework \ + -archive "$BUILD_DIR/Archives/$SCHEME-macOS.xcarchive" -framework "$SCHEME.framework" \ + -debug-symbols "$(realpath "$BUILD_DIR/Archives/$SCHEME-macOS.xcarchive/dSYMs/$SCHEME.framework.dSYM")" \ + -archive "$BUILD_DIR/Archives/$SCHEME-iOS.xcarchive" -framework "$SCHEME.framework" \ + -debug-symbols "$(realpath "$BUILD_DIR/Archives/$SCHEME-iOS.xcarchive/dSYMs/$SCHEME.framework.dSYM")" \ + -archive "$BUILD_DIR/Archives/$SCHEME-iOS-Simulator.xcarchive" -framework "$SCHEME.framework" \ + -debug-symbols "$(realpath "$BUILD_DIR/Archives/$SCHEME-iOS-Simulator.xcarchive/dSYMs/$SCHEME.framework.dSYM")" \ + -output "$BUILD_DIR/Frameworks/$SCHEME.xcframework" else - xcodebuild -create-xcframework \ - -framework $PACKAGE_NAME-iphonesimulator.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ - -framework $PACKAGE_NAME-iphoneos.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ - -framework $PACKAGE_NAME-macosx.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ - -output $PACKAGE_NAME.xcframework -fi \ No newline at end of file + xcodebuild -create-xcframework \ + -archive "$BUILD_DIR/Archives/$SCHEME-macOS.xcarchive" -framework "$SCHEME.framework" \ + -archive "$BUILD_DIR/Archives/$SCHEME-iOS.xcarchive" -framework "$SCHEME.framework" \ + -archive "$BUILD_DIR/Archives/$SCHEME-iOS-Simulator.xcarchive" -framework "$SCHEME.framework" \ + -output "$BUILD_DIR/Frameworks/$SCHEME.xcframework" +fi + +# Post-process swiftinterface files to replace OpenAttributeGraphCxx references with OpenAttributeGraph +find "$BUILD_DIR/Frameworks/$SCHEME.xcframework" -name "*.swiftinterface" | while read -r file; do + sed -i '' 's/OpenAttributeGraphCxx/OpenAttributeGraph/g' "$file" + echo "Processed: $file" +done + +# Delete private and package swiftinterface files +find "$BUILD_DIR/Frameworks/$SCHEME.xcframework" -name "*.package.swiftinterface" -delete +find "$BUILD_DIR/Frameworks/$SCHEME.xcframework" -name "*.private.swiftinterface" -delete + +# Copy module.modulemap into each framework's Modules directory +find "$BUILD_DIR/Frameworks/$SCHEME.xcframework" -type d -name "Modules" | while read -r modules_dir; do + cp "$BUILD_DIR/module.modulemap" "$modules_dir/" + echo "Copied modulemap to: $modules_dir" +done + +# Fix missing Headers symlink (macOS framework uses Versions/Current layout) +find "$BUILD_DIR/Frameworks/$SCHEME.xcframework" -type d -name "$SCHEME.framework" | while read -r framework_dir; do + if [ -d "$framework_dir/Versions" ] && [ ! -L "$framework_dir/Headers" ]; then + ln -s Versions/Current/Headers "$framework_dir/Headers" + echo "Added Headers symlink to: $framework_dir" + fi +done + +# Zip the framework, preserving symlinks +cd "$BUILD_DIR/Frameworks" +zip -r -y "$SCHEME.xcframework.zip" "$SCHEME.xcframework" +echo "Created $SCHEME.xcframework.zip" diff --git a/Scripts/build_xcframework_spm.sh b/Scripts/build_xcframework_spm.sh new file mode 100755 index 00000000..e12299c7 --- /dev/null +++ b/Scripts/build_xcframework_spm.sh @@ -0,0 +1,140 @@ +#!/bin/bash + +# DEPRECATED: Prefer Scripts/build_xcframework.sh which uses the xcodeproj. +# This SPM-based script is kept for reference only. + +# Script modified from https://docs.emergetools.com/docs/analyzing-a-spm-framework-ios + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd -P)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +PROJECT_BUILD_DIR="${PROJECT_BUILD_DIR:-"${PROJECT_ROOT}/build"}" +XCODEBUILD_BUILD_DIR="$PROJECT_BUILD_DIR/xcodebuild" +XCODEBUILD_DERIVED_DATA_PATH="$XCODEBUILD_BUILD_DIR/DerivedData" + +# Copy and modify modulemap +mkdir -p "$PROJECT_BUILD_DIR" +cat > "$PROJECT_BUILD_DIR/module.modulemap" << 'EOF' +framework module OpenAttributeGraph { + umbrella header "OpenAttributeGraph.h" + export * + module * { export * } +} +EOF + +# Parse arguments +DEBUG_INFO=false +PACKAGE_NAME="" + +while [[ $# -gt 0 ]]; do + case $1 in + --debug-info) + DEBUG_INFO=true + shift + ;; + *) + if [ -z "$PACKAGE_NAME" ]; then + PACKAGE_NAME="$1" + fi + shift + ;; + esac +done + +if [ -z "$PACKAGE_NAME" ]; then + echo "No package name provided. Using the first scheme found in the Package.swift." + PACKAGE_NAME=$(xcodebuild -list | awk 'schemes && NF>0 { print $1; exit } /Schemes:$/ { schemes = 1 }') + echo "Using: $PACKAGE_NAME" +fi + +echo "Building xcframework for package: $PACKAGE_NAME contains debug info: $DEBUG_INFO" + +build_framework() { + local sdk="$1" + local destination="$2" + local scheme="$3" + + local XCODEBUILD_ARCHIVE_PATH="./build/$scheme-$sdk.xcarchive" + + rm -rf "$XCODEBUILD_ARCHIVE_PATH" + + xcodebuild archive \ + -scheme $scheme \ + -archivePath $XCODEBUILD_ARCHIVE_PATH \ + -derivedDataPath "$XCODEBUILD_DERIVED_DATA_PATH" \ + -sdk "$sdk" \ + -destination "$destination" \ + BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ + INSTALL_PATH='Library/Frameworks' \ + OTHER_SWIFT_FLAGS=-no-verify-emitted-module-interface + + if [ "$sdk" = "macosx" ]; then + FRAMEWORK_MODULES_PATH="$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Versions/Current/Modules" + FRAMEWORK_HEADERS_PATH="$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Versions/Current/Headers" + mkdir -p "$FRAMEWORK_MODULES_PATH" + mkdir -p "$FRAMEWORK_HEADERS_PATH" + cp -r \ + "$XCODEBUILD_DERIVED_DATA_PATH/Build/Intermediates.noindex/ArchiveIntermediates/$scheme/BuildProductsPath/Release/$scheme.swiftmodule" \ + "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule" + # Replace OpenAttributeGraphCxx with OpenAttributeGraph in swiftinterface files + find "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule" -name "*.swiftinterface" -exec sed -i '' 's/OpenAttributeGraphCxx/OpenAttributeGraph/g' {} \; + cp -r \ + "$PROJECT_ROOT/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph"/* \ + "$FRAMEWORK_HEADERS_PATH/" 2>/dev/null || true + cp "$PROJECT_BUILD_DIR/module.modulemap" \ + "$FRAMEWORK_MODULES_PATH/module.modulemap" 2>/dev/null || true + rm -rf "$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Modules" + rm -rf "$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Headers" + ln -s Versions/Current/Modules "$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Modules" + ln -s Versions/Current/Headers "$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Headers" + else + FRAMEWORK_MODULES_PATH="$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Modules" + FRAMEWORK_HEADERS_PATH="$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Headers" + mkdir -p "$FRAMEWORK_MODULES_PATH" + mkdir -p "$FRAMEWORK_HEADERS_PATH" + cp -r \ + "$XCODEBUILD_DERIVED_DATA_PATH/Build/Intermediates.noindex/ArchiveIntermediates/$scheme/BuildProductsPath/Release-$sdk/$scheme.swiftmodule" \ + "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule" + # Replace OpenAttributeGraphCxx with OpenAttributeGraph in swiftinterface files + find "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule" -name "*.swiftinterface" -exec sed -i '' 's/OpenAttributeGraphCxx/OpenAttributeGraph/g' {} \; + cp -r \ + "$PROJECT_ROOT/Sources/OpenAttributeGraphCxx/include/OpenAttributeGraph"/* \ + "$FRAMEWORK_HEADERS_PATH/" 2>/dev/null || true + cp "$PROJECT_BUILD_DIR/module.modulemap" \ + "$FRAMEWORK_MODULES_PATH/module.modulemap" 2>/dev/null || true + fi + + # Delete private and package swiftinterface + rm -f "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule/*.package.swiftinterface" + rm -f "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule/*.private.swiftinterface" +} + +build_framework "iphonesimulator" "generic/platform=iOS Simulator" "$PACKAGE_NAME" +build_framework "iphoneos" "generic/platform=iOS" "$PACKAGE_NAME" +build_framework "macosx" "generic/platform=macOS" "$PACKAGE_NAME" + +echo "Builds completed successfully." + +cd $PROJECT_BUILD_DIR + +rm -rf "$PACKAGE_NAME.xcframework" + +if [ "$DEBUG_INFO" = true ]; then + echo "Creating xcframework with debug symbols..." + xcodebuild -create-xcframework \ + -framework $PACKAGE_NAME-iphonesimulator.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ + -debug-symbols "$(realpath $PACKAGE_NAME-iphonesimulator.xcarchive/dSYMs/$PACKAGE_NAME.framework.dSYM)" \ + -framework $PACKAGE_NAME-iphoneos.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ + -debug-symbols "$(realpath $PACKAGE_NAME-iphoneos.xcarchive/dSYMs/$PACKAGE_NAME.framework.dSYM)" \ + -framework $PACKAGE_NAME-macosx.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ + -debug-symbols "$(realpath $PACKAGE_NAME-macosx.xcarchive/dSYMs/$PACKAGE_NAME.framework.dSYM)" \ + -output $PACKAGE_NAME.xcframework +else + xcodebuild -create-xcframework \ + -framework $PACKAGE_NAME-iphonesimulator.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ + -framework $PACKAGE_NAME-iphoneos.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ + -framework $PACKAGE_NAME-macosx.xcarchive/Products/Library/Frameworks/$PACKAGE_NAME.framework \ + -output $PACKAGE_NAME.xcframework +fi \ No newline at end of file