diff --git a/examples/firebase_example/.bazelrc b/examples/firebase_example/.bazelrc index 34dd1e78a..56d351488 100644 --- a/examples/firebase_example/.bazelrc +++ b/examples/firebase_example/.bazelrc @@ -7,11 +7,14 @@ import %workspace%/../../ci.bazelrc # Try to import a local.rc file; typically, written by CI try-import %workspace%/../../local.bazelrc -# Per https://github.com/firebase/firebase-ios-sdk/blob/master/Package.swift#L1322-L1323 # NOTE: Puposefully not specifying --copt='-std=c99' as it is applied to # objc_library targets that contain Objective-C++ files. Tried using # --per_file_copt to exclude .mm files, but did not have success. # https://stackoverflow.com/questions/40260242/how-to-set-c-standard-version-when-build-with-bazel/43388168#43388168 +# +# # Required by firebase-ios-sdk, googleappmeasurement, googledatatransport, googleutilities +# build --copt='-std=c99' +# Required by firebase-ios-sdk, googleappmeasurement, googledatatransport, googleutilities, leveldb build --cxxopt='-std=gnu++14' # Firebase SPM support requires `-ObjC` linker option. diff --git a/examples/firebase_example/swift_deps_index.json b/examples/firebase_example/swift_deps_index.json index d4b142546..22b85d0b6 100644 --- a/examples/firebase_example/swift_deps_index.json +++ b/examples/firebase_example/swift_deps_index.json @@ -1554,7 +1554,9 @@ "commit": "837d4af6ead57cec1fc38007892500d3139c7556", "remote": "https://github.com/firebase/firebase-ios-sdk", "version": "10.16.0" - } + }, + "cLanguageStandard": "c99", + "cxxLanguageStandard": "gnu++14" }, { "name": "swiftpkg_googleappmeasurement", @@ -1563,7 +1565,9 @@ "commit": "56f681586ff006a7982b53dc94082eea31971acf", "remote": "https://github.com/google/GoogleAppMeasurement.git", "version": "10.16.0" - } + }, + "cLanguageStandard": "c99", + "cxxLanguageStandard": "gnu++14" }, { "name": "swiftpkg_googledatatransport", @@ -1572,7 +1576,9 @@ "commit": "5056b15c5acbb90cd214fe4d6138bdf5a740e5a8", "remote": "https://github.com/google/GoogleDataTransport.git", "version": "9.2.0" - } + }, + "cLanguageStandard": "c99", + "cxxLanguageStandard": "gnu++14" }, { "name": "swiftpkg_googleutilities", @@ -1581,7 +1587,9 @@ "commit": "0543562f85620b5b7c510c6bcbef75b562a5127b", "remote": "https://github.com/google/GoogleUtilities.git", "version": "7.11.0" - } + }, + "cLanguageStandard": "c99", + "cxxLanguageStandard": "gnu++14" }, { "name": "swiftpkg_grpc_binary", @@ -1617,7 +1625,8 @@ "commit": "0706abcc6b0bd9cedfbb015ba840e4a780b5159b", "remote": "https://github.com/firebase/leveldb.git", "version": "1.22.2" - } + }, + "cxxLanguageStandard": "gnu++14" }, { "name": "swiftpkg_nanopb", diff --git a/examples/soto_example/.bazelrc b/examples/soto_example/.bazelrc index 3ac840cb0..bef170e0d 100644 --- a/examples/soto_example/.bazelrc +++ b/examples/soto_example/.bazelrc @@ -10,4 +10,5 @@ try-import %workspace%/../../local.bazelrc # The CNIOBoringSSL uses C++14 features like 'enable_if_t' macro support. # For more details on how to enable this in Bazel: # https://stackoverflow.com/questions/40260242/how-to-set-c-standard-version-when-build-with-bazel/43388168#43388168 +# Required by swift-nio-ssl build --cxxopt='-std=c++14' diff --git a/examples/soto_example/swift_deps_index.json b/examples/soto_example/swift_deps_index.json index 4a40f2c40..d92e1cf13 100644 --- a/examples/soto_example/swift_deps_index.json +++ b/examples/soto_example/swift_deps_index.json @@ -7228,7 +7228,8 @@ "commit": "4fb7ead803e38949eb1d6fabb849206a72c580f3", "remote": "https://github.com/apple/swift-nio-ssl.git", "version": "2.23.0" - } + }, + "cxxLanguageStandard": "c++14" }, { "name": "swiftpkg_swift_nio_transport_services", diff --git a/examples/vapor_example/.bazelrc b/examples/vapor_example/.bazelrc index f47fd6a85..783721137 100644 --- a/examples/vapor_example/.bazelrc +++ b/examples/vapor_example/.bazelrc @@ -10,5 +10,8 @@ try-import %workspace%/../../local.bazelrc # The CNIOBoringSSL uses C++14 features like 'enable_if_t' macro support. # For more details on how to enable this in Bazel: # https://stackoverflow.com/questions/40260242/how-to-set-c-standard-version-when-build-with-bazel/43388168#43388168 +# +# # Required by swift-crypto +# build --cxxopt='-std=c++11' +# Required by swift-nio-ssl build --cxxopt='-std=c++14' - diff --git a/examples/vapor_example/swift/deps_index.json b/examples/vapor_example/swift/deps_index.json index f763dd928..cf7d2bc81 100644 --- a/examples/vapor_example/swift/deps_index.json +++ b/examples/vapor_example/swift/deps_index.json @@ -1432,7 +1432,8 @@ "commit": "75ec60b8b4cc0f085c3ac414f3dca5625fa3588e", "remote": "https://github.com/apple/swift-crypto.git", "version": "2.2.4" - } + }, + "cxxLanguageStandard": "c++11" }, { "name": "swiftpkg_swift_log", @@ -1486,7 +1487,8 @@ "commit": "320bd978cceb8e88c125dcbb774943a92f6286e9", "remote": "https://github.com/apple/swift-nio-ssl.git", "version": "2.25.0" - } + }, + "cxxLanguageStandard": "c++14" }, { "name": "swiftpkg_swift_nio_transport_services", diff --git a/examples/xcmetrics_example/.bazelrc b/examples/xcmetrics_example/.bazelrc index f47fd6a85..0e8f2ac37 100644 --- a/examples/xcmetrics_example/.bazelrc +++ b/examples/xcmetrics_example/.bazelrc @@ -10,5 +10,8 @@ try-import %workspace%/../../local.bazelrc # The CNIOBoringSSL uses C++14 features like 'enable_if_t' macro support. # For more details on how to enable this in Bazel: # https://stackoverflow.com/questions/40260242/how-to-set-c-standard-version-when-build-with-bazel/43388168#43388168 +# +# # Required by jwt-kit, swift-crypto +# build --cxxopt='-std=c++11' +# Required by swift-nio-ssl build --cxxopt='-std=c++14' - diff --git a/examples/xcmetrics_example/swift_deps_index.json b/examples/xcmetrics_example/swift_deps_index.json index 68d94a473..487bcf880 100644 --- a/examples/xcmetrics_example/swift_deps_index.json +++ b/examples/xcmetrics_example/swift_deps_index.json @@ -7024,7 +7024,8 @@ "commit": "dcd78f07e092ac9138327e2bfbb0687a55a80850", "remote": "https://github.com/vapor/jwt-kit.git", "version": "4.8.0" - } + }, + "cxxLanguageStandard": "c++11" }, { "name": "swiftpkg_mobius.swift", @@ -7231,7 +7232,8 @@ "commit": "75ec60b8b4cc0f085c3ac414f3dca5625fa3588e", "remote": "https://github.com/apple/swift-crypto.git", "version": "2.2.4" - } + }, + "cxxLanguageStandard": "c++11" }, { "name": "swiftpkg_swift_log", @@ -7285,7 +7287,8 @@ "commit": "4fb7ead803e38949eb1d6fabb849206a72c580f3", "remote": "https://github.com/apple/swift-nio-ssl.git", "version": "2.23.0" - } + }, + "cxxLanguageStandard": "c++14" }, { "name": "swiftpkg_swift_nio_transport_services", diff --git a/gazelle/internal/spdump/manifest.go b/gazelle/internal/spdump/manifest.go index 366a686be..37e0a7f8b 100644 --- a/gazelle/internal/spdump/manifest.go +++ b/gazelle/internal/spdump/manifest.go @@ -20,9 +20,11 @@ func NewManifestFromJSON(bytes []byte) (*Manifest, error) { // A Manifest represents a Swift manifest as serialized by `swift package dump-package`. type Manifest struct { - Name string - Dependencies []Dependency - Platforms []Platform - Products []Product - Targets Targets + Name string + Dependencies []Dependency + Platforms []Platform + Products []Product + Targets Targets + CLanguageStandard string `json:"cLanguageStandard"` + CxxLanguageStandard string `json:"cxxLanguageStandard"` } diff --git a/gazelle/internal/spdump/manifest_test.go b/gazelle/internal/spdump/manifest_test.go index 23c035f31..9dfd0c754 100644 --- a/gazelle/internal/spdump/manifest_test.go +++ b/gazelle/internal/spdump/manifest_test.go @@ -21,7 +21,7 @@ func TestNewManifestFromJSON(t *testing.T) { }, Requirement: &spdump.DependencyRequirement{ Ranges: []*spdump.VersionRange{ - &spdump.VersionRange{LowerBound: "1.2.0", UpperBound: "2.0.0"}, + {LowerBound: "1.2.0", UpperBound: "2.0.0"}, }, }, }, @@ -68,6 +68,8 @@ func TestNewManifestFromJSON(t *testing.T) { Settings: []spdump.TargetSetting{}, }, }, + CLanguageStandard: "c99", + CxxLanguageStandard: "gnu++14", } manifest, err := spdump.NewManifestFromJSON([]byte(swiftPackageJSONStr)) assert.NoError(t, err) @@ -76,8 +78,8 @@ func TestNewManifestFromJSON(t *testing.T) { const swiftPackageJSONStr = ` { - "cLanguageStandard" : null, - "cxxLanguageStandard" : null, + "cLanguageStandard" : "c99", + "cxxLanguageStandard" : "gnu++14", "dependencies" : [ { "sourceControl" : [ diff --git a/gazelle/internal/swift/dependency_index.go b/gazelle/internal/swift/dependency_index.go index 3d63db70e..ef1094466 100644 --- a/gazelle/internal/swift/dependency_index.go +++ b/gazelle/internal/swift/dependency_index.go @@ -142,6 +142,10 @@ func (di *DependencyIndex) DirectDepPackages() []*Package { return results } +func (di *DependencyIndex) Packages() []*Package { + return di.packageIndex.Packages() +} + // Resolve type ModuleResolutionResult struct { diff --git a/gazelle/internal/swift/package.go b/gazelle/internal/swift/package.go index cfd021279..3ad36aaf2 100644 --- a/gazelle/internal/swift/package.go +++ b/gazelle/internal/swift/package.go @@ -8,10 +8,12 @@ import ( ) type Package struct { - Name string `json:"name"` - Identity string `json:"identity"` - Local *LocalPackage `json:"local,omitempty"` - Remote *RemotePackage `json:"remote,omitempty"` + Name string `json:"name"` + Identity string `json:"identity"` + Local *LocalPackage `json:"local,omitempty"` + Remote *RemotePackage `json:"remote,omitempty"` + CLanguageStandard string `json:"cLanguageStandard,omitempty"` + CxxLanguageStandard string `json:"cxxLanguageStandard,omitempty"` } type LocalPackage struct { @@ -33,7 +35,18 @@ func NewPackageFromBazelRepo( patch *Patch, ) (*Package, error) { var err error - p := Package{Name: bzlRepo.Name, Identity: bzlRepo.Identity} + cLangStd := "" + cxxLangStd := "" + if bzlRepo.PkgInfo != nil { + cLangStd = bzlRepo.PkgInfo.CLanguageStandard + cxxLangStd = bzlRepo.PkgInfo.CxxLanguageStandard + } + p := Package{ + Name: bzlRepo.Name, + Identity: bzlRepo.Identity, + CLanguageStandard: cLangStd, + CxxLanguageStandard: cxxLangStd, + } if bzlRepo.Pin != nil { p.Remote, err = remotePackageFromPin(bzlRepo.Name, bzlRepo.Pin) if err != nil { diff --git a/gazelle/internal/swiftpkg/package_info.go b/gazelle/internal/swiftpkg/package_info.go index 729276f1e..0c5ad7f9d 100644 --- a/gazelle/internal/swiftpkg/package_info.go +++ b/gazelle/internal/swiftpkg/package_info.go @@ -12,14 +12,16 @@ import ( // A PackageInfo encapsulates all of the information about a Swift package. type PackageInfo struct { - Name string - DisplayName string - Path string - ToolsVersion string - Targets Targets - Platforms []*Platform - Products []*Product - Dependencies Dependencies + Name string + DisplayName string + Path string + ToolsVersion string + Targets Targets + Platforms []*Platform + Products []*Product + Dependencies Dependencies + CLanguageStandard string + CxxLanguageStandard string } // NewPackageInfo returns the Swift package information from a Swift package on disk. @@ -90,14 +92,16 @@ func NewPackageInfo(sw swiftbin.Executor, dir string) (*PackageInfo, error) { } return &PackageInfo{ - Name: descManifest.Name, - DisplayName: descManifest.ManifestDisplayName, - Path: descManifest.Path, - ToolsVersion: descManifest.ToolsVersion, - Targets: targets, - Platforms: platforms, - Products: products, - Dependencies: deps, + Name: descManifest.Name, + DisplayName: descManifest.ManifestDisplayName, + Path: descManifest.Path, + ToolsVersion: descManifest.ToolsVersion, + Targets: targets, + Platforms: platforms, + Products: products, + Dependencies: deps, + CLanguageStandard: dumpManifest.CLanguageStandard, + CxxLanguageStandard: dumpManifest.CxxLanguageStandard, }, nil } diff --git a/gazelle/update_repos.go b/gazelle/update_repos.go index 9326757c8..b9c314b52 100644 --- a/gazelle/update_repos.go +++ b/gazelle/update_repos.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/bazelbuild/bazel-gazelle/language" "github.com/bazelbuild/bazel-gazelle/rule" @@ -143,6 +144,9 @@ func importReposFromPackageManifest(args language.ImportReposArgs) language.Impo di.AddPackage(pkg) } + // Print information about language standards + printLanguageStandardInfo(di.Packages()) + // Output a use_repo names for bzlmod. if err := writeBzlmodUseRepoNames(di, sc); err != nil { result.Error = err @@ -225,6 +229,48 @@ func readResolvedPkgPins(resolvedPkgPath string) (map[string]*spreso.Pin, error) return pinsByIdentity, nil } +func printLanguageStandardInfo(pkgs []*swift.Package) { + cLangStds := make(map[string][]string) + cxxLangStds := make(map[string][]string) + for _, pkg := range pkgs { + if pkg.CLanguageStandard != "" { + idents := cLangStds[pkg.CLanguageStandard] + idents = append(idents, pkg.Identity) + cLangStds[pkg.CLanguageStandard] = idents + } + if pkg.CxxLanguageStandard != "" { + idents := cxxLangStds[pkg.CxxLanguageStandard] + idents = append(idents, pkg.Identity) + cxxLangStds[pkg.CxxLanguageStandard] = idents + } + } + var outputLines []string + if len(cLangStds) > 0 { + for std, idents := range cLangStds { + outputLines = append(outputLines, + fmt.Sprintf("# Required by %s", strings.Join(idents, ", ")), + fmt.Sprintf("build --copt='-std=%s'", std), + ) + } + } + if len(cxxLangStds) > 0 { + for std, idents := range cxxLangStds { + outputLines = append(outputLines, + fmt.Sprintf("# Required by %s", strings.Join(idents, ", ")), + fmt.Sprintf("build --cxxopt='-std=%s'", std), + ) + } + } + + if len(outputLines) > 0 { + preamble := `One or more of your Swift packages has defined language standard requirements. +Consider adding the following to your .bazelrc file: + +` + fmt.Println(preamble + strings.Join(outputLines, "\n")) + } +} + func writeBzlmodUseRepoNames(di *swift.DependencyIndex, sc *swiftcfg.SwiftConfig) error { if !sc.UpdateBzlmodUseRepoNames { return nil