Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/check_modulemaps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Check Module Map Files

on:
pull_request:
branches:
- '**'

jobs:
verify:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Verify generated private module maps
run: ./Swift/ModuleMap/generate_private_modulemap.sh --check
5 changes: 3 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,16 @@ iOS app-hosted test schemes:
- Community Edition code must not depend on Enterprise Edition code.
- Enterprise Edition code may extend Community Edition behavior through EE sources or `COUCHBASE_ENTERPRISE` guards.
- Swift APIs mirror Obj-C APIs; public API changes usually require updates in both layers.
- Swift-to-Obj-C bridging is controlled by `Swift/CouchbaseLiteSwift.private.modulemap` and `../couchbase-lite-ios-ee/Sources/Swift/CouchbaseLiteSwift.private.modulemap`.
- If a new Obj-C header must be visible to Swift, update the appropriate private module map.
- Swift-to-Obj-C bridging is controlled by the generated private module maps in `Swift/ModuleMap/Generated/` (both editions; generated from the header list templates in `Swift/ModuleMap/`).
- To make a new Obj-C header visible to Swift: add a CE header to `Swift/ModuleMap/CouchbaseLiteSwift.private.txt`, or an EE header to `Swift/ModuleMap/CouchbaseLiteSwift-EE.private.txt`, then run `Swift/ModuleMap/generate_private_modulemap.sh` and commit the regenerated module maps.
- Public Obj-C exported symbols are defined by `Objective-C/Exports/CBL.txt` and `Objective-C/Exports/CBL_EE.txt`.

## Guardrails

- Do not hand-edit `CouchbaseLite.xcodeproj/project.pbxproj`.
- If a task requires new files or project membership changes, ask the developer to make them in Xcode.
- Do not edit generated export files in `Objective-C/Exports/Generated/` directly. Update the templates and run `Objective-C/Exports/generate_exports.sh` instead.
- Do not edit the generated private module maps in `Swift/ModuleMap/Generated/` directly. Update the header list templates and run `Swift/ModuleMap/generate_private_modulemap.sh` instead (see Architecture Notes).

## Build and Test

Expand Down
30 changes: 26 additions & 4 deletions CouchbaseLite.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2461,6 +2461,9 @@
40AA72972C28B1A3007FB1E0 /* VectorSearchTest+Lazy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "VectorSearchTest+Lazy.m"; sourceTree = "<group>"; };
40AA72A12C28B1F2007FB1E0 /* VectorSearchTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VectorSearchTest.h; sourceTree = "<group>"; };
40C5FD5A2B9946E6004BFD3B /* CBLVectorIndexTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CBLVectorIndexTypes.h; sourceTree = "<group>"; };
40CC4B76302BE6D30002386D /* CouchbaseLiteSwift-EE.private.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "CouchbaseLiteSwift-EE.private.txt"; sourceTree = "<group>"; };
40CC4B77302BE6E40002386D /* CouchbaseLiteSwift.private.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CouchbaseLiteSwift.private.txt; sourceTree = "<group>"; };
40CC4B79302BF1620002386D /* CouchbaseLiteSwift-EE.private.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = "CouchbaseLiteSwift-EE.private.modulemap"; sourceTree = "<group>"; };
40D6BCBF2DDD183000F209D7 /* MultipeerReplicatorConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipeerReplicatorConfiguration.swift; sourceTree = "<group>"; };
40D6BCC12DDD191C00F209D7 /* MultipeerCertificateAuthenticator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipeerCertificateAuthenticator.swift; sourceTree = "<group>"; };
40D6BCC32DDD19D900F209D7 /* PeerID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeerID.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2496,12 +2499,13 @@
40E46B122DD6A7B5007E495D /* CBLReplicatorStatus+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CBLReplicatorStatus+Internal.h"; sourceTree = "<group>"; };
40E46B172DD6A808007E495D /* CBLConflictResolverService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CBLConflictResolverService.h; sourceTree = "<group>"; };
40E46B182DD6A808007E495D /* CBLConflictResolverService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CBLConflictResolverService.m; sourceTree = "<group>"; };
40E905462B5B6D9D00EDF483 /* CouchbaseLiteSwift.private.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = CouchbaseLiteSwift.private.modulemap; sourceTree = "<group>"; };
40ECAE852E0E08CC00C109A6 /* Precondition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Precondition.swift; sourceTree = "<group>"; };
40ECAE882E0E0B0F00C109A6 /* CBLPrecondition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CBLPrecondition.h; sourceTree = "<group>"; };
40ECAE892E0E0B0F00C109A6 /* CBLPrecondition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CBLPrecondition.m; sourceTree = "<group>"; };
40EF68102B71891A00F0CB50 /* remove_private_module.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = remove_private_module.sh; sourceTree = "<group>"; };
40EF690A2B77564000F0CB50 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
40F52B1D3026ED0F009C5F9E /* CouchbaseLiteSwift.private.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = CouchbaseLiteSwift.private.modulemap; sourceTree = "<group>"; };
40F52B203026ED0F009C5F9E /* generate_private_modulemap.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = generate_private_modulemap.sh; sourceTree = "<group>"; };
40FC1AA32B9286E700394276 /* CBLEncryptionKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CBLEncryptionKey.m; sourceTree = "<group>"; };
40FC1AA42B9286E700394276 /* CBLDatabase+Encryption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CBLDatabase+Encryption.h"; sourceTree = "<group>"; };
40FC1AA52B9286E700394276 /* CBLDatabaseConfiguration+Encryption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CBLDatabaseConfiguration+Encryption.h"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2587,7 +2591,6 @@
40FC1C402B928C1600394276 /* ListenerCertificateAuthenticator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListenerCertificateAuthenticator.swift; sourceTree = "<group>"; };
40FC1C412B928C1600394276 /* ListenerPasswordAuthenticator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListenerPasswordAuthenticator.swift; sourceTree = "<group>"; };
40FC1C422B928C1600394276 /* ListenerAuthenticator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListenerAuthenticator.swift; sourceTree = "<group>"; };
40FC1C432B928C1600394276 /* CouchbaseLiteSwift.private.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = CouchbaseLiteSwift.private.modulemap; sourceTree = "<group>"; };
40FC1C452B928C1600394276 /* MessageEndpointConnection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageEndpointConnection.swift; sourceTree = "<group>"; };
40FC1C462B928C1600394276 /* ClientCertificateAuthenticator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClientCertificateAuthenticator.swift; sourceTree = "<group>"; };
40FC1C472B928C1600394276 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3243,8 +3246,8 @@
409389E72D4AB7DE00691393 /* LogSink */,
40D6BCC62DDD2C2D00F209D7 /* Support */,
27BE3B491E4E45CB0012B74A /* Tests */,
40F52B213026ED0F009C5F9E /* ModuleMap */,
275F92761E4D30A4007FD5A2 /* CouchbaseLiteSwift.h */,
40E905462B5B6D9D00EDF483 /* CouchbaseLiteSwift.private.modulemap */,
275F92771E4D30A4007FD5A2 /* Info.plist */,
);
path = Swift;
Expand Down Expand Up @@ -3447,6 +3450,26 @@
path = Resources;
sourceTree = "<group>";
};
40F52B1E3026ED0F009C5F9E /* Generated */ = {
isa = PBXGroup;
children = (
40F52B1D3026ED0F009C5F9E /* CouchbaseLiteSwift.private.modulemap */,
40CC4B79302BF1620002386D /* CouchbaseLiteSwift-EE.private.modulemap */,
);
path = Generated;
sourceTree = "<group>";
};
40F52B213026ED0F009C5F9E /* ModuleMap */ = {
isa = PBXGroup;
children = (
40F52B1E3026ED0F009C5F9E /* Generated */,
40CC4B77302BE6E40002386D /* CouchbaseLiteSwift.private.txt */,
40CC4B76302BE6D30002386D /* CouchbaseLiteSwift-EE.private.txt */,
40F52B203026ED0F009C5F9E /* generate_private_modulemap.sh */,
);
path = ModuleMap;
sourceTree = "<group>";
};
40FC1AA02B9286E700394276 /* Objective-C */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -3677,7 +3700,6 @@
40D6BCBE2DDD17FF00F209D7 /* Multipeer */,
40FC1C4C2B928C1600394276 /* Query */,
40FC1C442B928C1600394276 /* Replicator */,
40FC1C432B928C1600394276 /* CouchbaseLiteSwift.private.modulemap */,
);
name = Swift;
path = "../couchbase-lite-ios-ee/Sources/Swift";
Expand Down
1 change: 1 addition & 0 deletions Scripts/pull_request_build_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ else
cd couchbase-lite-ios
fi


# Minimum Matrix:
# - Run swift tests on iOS platform
# - Run objective-C tests on macOS platform
Expand Down
13 changes: 13 additions & 0 deletions Scripts/remove_private_module.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

set -e

# Only strip the private module from Release builds used for packaging.
# Development (Debug) builds must keep the full private modulemap in the built
# framework; the Xcode indexer resolves CouchbaseLiteSwift_Private from the
# built products, and stripping it there makes all private Obj-C classes
# unresolvable in the editor.
case "${CONFIGURATION}" in
Release*) ;;
*)
echo "Skipping private module removal for configuration '${CONFIGURATION}'"
exit 0
;;
esac

FRAMEWORK_DIR=${TARGET_BUILD_DIR}/${PRODUCT_NAME}${WRAPPER_SUFFIX}

# Remove private headers from module.private.modulemap:
Expand Down
46 changes: 46 additions & 0 deletions Swift/ModuleMap/CouchbaseLiteSwift-EE.private.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# EE-only header list, appended to the CE header list in the generated EE
# module map. Lines starting with '#' are template comments and are not copied
# to the output.
#
// Enterprise Edition:
header "CBLClientCertificateAuthenticator.h"
header "CBLCoreMLPredictiveModel.h"
header "CBLDatabase+Encryption.h"
header "CBLDatabase+Prediction.h"
header "CBLDatabaseConfiguration+Encryption.h"
header "CBLDatabaseEndpoint.h"
header "CBLEncryptionKey.h"
header "CBLExtension.h"
header "CBLIndexBuilder+Prediction.h"
header "CBLIndexUpdater.h"
header "CBLListenerAuthenticator.h"
header "CBLListenerCertificateAuthenticator.h"
header "CBLListenerPasswordAuthenticator.h"
header "CBLMessage.h"
header "CBLMessageEndpoint.h"
header "CBLMessageEndpointConnection.h"
header "CBLMessageEndpointListener.h"
header "CBLMessagingError.h"
header "CBLMultipeerCertificateAuthenticator.h"
header "CBLMultipeerCollectionConfiguration.h"
header "CBLMultipeerEventTypes.h"
header "CBLMultipeerReplicator.h"
header "CBLMultipeerReplicatorConfiguration.h"
header "CBLMultipeerTransportTypes.h"
header "CBLPeerID.h"
header "CBLPeerInfo.h"
header "CBLPrediction.h"
header "CBLPrediction+Swift.h"
header "CBLPredictiveIndex.h"
header "CBLProtocolType.h"
header "CBLQueryFunction+Prediction.h"
header "CBLQueryFunction+Vector.h"
header "CBLReplicatorConfiguration+ServerCert.h"
header "CBLTLSIdentity.h"
header "CBLTLSIdentity+Swift.h"
header "CBLURLEndpointListener.h"
header "CBLURLEndpointListener+Swift.h"
header "CBLURLEndpointListenerConfiguration.h"
header "CBLVectorEncoding.h"
header "CBLVectorIndexConfiguration.h"
header "CBLVectorIndexTypes.h"
99 changes: 99 additions & 0 deletions Swift/ModuleMap/CouchbaseLiteSwift.private.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Header list for the CouchbaseLiteSwift_Private module (CE).
# Lines starting with '#' are template comments and are not copied to the output.
# Everything else is inserted verbatim into the generated module maps by
# generate_private_modulemap.sh in this directory.
#
header "CBLArray.h"
header "CBLArrayFragment.h"
header "CBLArrayIndexConfiguration.h"
header "CBLAuthenticator.h"
header "CBLBasicAuthenticator.h"
header "CBLBlob.h"
header "CBLCollection.h"
header "CBLCollectionChange.h"
header "CBLCollectionChangeObservable.h"
header "CBLCollectionConfiguration.h"
header "CBLConflict.h"
header "CBLConflictResolver.h"
header "CBLConsoleLogSink.h"
header "CBLCustomLogSink.h"
header "CBLDatabase.h"
header "CBLDatabaseConfiguration.h"
header "CBLDictionary.h"
header "CBLDictionaryFragment.h"
header "CBLDocument.h"
header "CBLDocumentChange.h"
header "CBLDocumentFlags.h"
header "CBLDocumentFragment.h"
header "CBLDocumentReplication.h"
header "CBLEdition.h"
header "CBLEncoder.h"
header "CBLEndpoint.h"
header "CBLErrors.h"
header "CBLFileLogSink.h"
header "CBLFragment.h"
header "CBLFullTextIndex.h"
header "CBLFullTextIndexConfiguration.h"
header "CBLIndex.h"
header "CBLIndexable.h"
header "CBLIndexBuilder.h"
header "CBLIndexConfiguration.h"
header "CBLListenerToken.h"
header "CBLLogSinks.h"
header "CBLLogTypes.h"
header "CBLQueryChange.h"
header "CBLMutableArray.h"
header "CBLMutableArrayFragment.h"
header "CBLMutableDictionary.h"
header "CBLMutableDictionaryFragment.h"
header "CBLMutableDocument.h"
header "CBLMutableFragment.h"
header "CBLNewDictionary.h"
header "CBLQuery.h"
header "CBLQuery+JSON.h"
header "CBLQueryArrayExpression.h"
header "CBLQueryArrayFunction.h"
header "CBLQueryBuilder.h"
header "CBLQueryCollation.h"
header "CBLQueryDataSource.h"
header "CBLQueryExpression.h"
header "CBLQueryFactory.h"
header "CBLQueryFunction.h"
header "CBLQueryFullTextFunction.h"
header "CBLQueryIndex.h"
header "CBLQueryJoin.h"
header "CBLQueryLimit.h"
header "CBLQueryMeta.h"
header "CBLQueryOrdering.h"
header "CBLQueryParameters.h"
header "CBLQueryResult.h"
header "CBLQueryResultSet.h"
header "CBLQuerySelectResult.h"
header "CBLQueryVariableExpression.h"
header "CBLReplicator.h"
header "CBLReplicatorChange.h"
header "CBLReplicatorConfiguration.h"
header "CBLReplicatorStatus.h"
header "CBLReplicatorTypes.h"
header "CBLScope.h"
header "CBLSessionAuthenticator.h"
header "CBLURLEndpoint.h"
header "CBLValueIndex.h"
header "CBLValueIndexConfiguration.h"
header "CBLCollectionTypes.h"
header "CBLDefaults.h"
header "CBLQueryFullTextIndexExpressionProtocol.h"

// Internal
header "CBLQueryFullTextIndexExpression.h"
header "CBLPrecondition.h"

// Swift Extensions:
header "CBLArray+Swift.h"
header "CBLBlob+Swift.h"
header "CBLCollection+Swift.h"
header "CBLDatabase+Swift.h"
header "CBLDictionary+Swift.h"
header "CBLConflictResolverBridge.h"
header "CBLCollectionConfiguration+Swift.h"
header "CBLLog+Swift.h"
Loading
Loading