diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index fb3d64a90d..a2b21671c5 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -415,6 +415,7 @@ syn keyword cmakeProperty contained \ Swift_LANGUAGE_VERSION \ Swift_MODULE_DIRECTORY \ Swift_MODULE_NAME + \ Swift_PACKAGE_NAME \ Swift_SEPARATE_MODULE_EMISSION \ TARGET_ARCHIVES_MAY_BE_SHARED_LIBS \ TARGET_MESSAGES diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 4ec3b6e17f..3638cf6530 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -427,6 +427,7 @@ Properties on Targets /prop_tgt/Swift_LANGUAGE_VERSION /prop_tgt/Swift_MODULE_DIRECTORY /prop_tgt/Swift_MODULE_NAME + /prop_tgt/Swift_PACKAGE_NAME /prop_tgt/Swift_SEPARATE_MODULE_EMISSION /prop_tgt/SYMBOLIC /prop_tgt/SYSTEM diff --git a/Help/prop_tgt/Swift_PACKAGE_NAME.rst b/Help/prop_tgt/Swift_PACKAGE_NAME.rst new file mode 100644 index 0000000000..c5d914318d --- /dev/null +++ b/Help/prop_tgt/Swift_PACKAGE_NAME.rst @@ -0,0 +1,18 @@ +Swift_PACKAGE_NAME +------------------ + +.. versionadded:: 4.4 + +Specify the Swift package name for a target. + +This property sets the package name passed to the Swift compiler via the +``-package-name`` flag, which enables the package access control in Swift +code. + +.. note:: + + Package access control was added in Swift 5.8 and Xcode 15. This target + property has no effect when using an earlier version of Swift or Xcode. + +Setting this property to the empty string will result in the target being +compiled without a package name. diff --git a/Help/release/dev/swift-package-name.rst b/Help/release/dev/swift-package-name.rst new file mode 100644 index 0000000000..2f42f0bea6 --- /dev/null +++ b/Help/release/dev/swift-package-name.rst @@ -0,0 +1,5 @@ +swift-package-name +------------------ + +* The :prop_tgt:`Swift_PACKAGE_NAME` target property was added to + specify a Swift package name. diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake index d6d96ece35..5743fa1fea 100644 --- a/Modules/CMakeSwiftInformation.cmake +++ b/Modules/CMakeSwiftInformation.cmake @@ -59,6 +59,7 @@ set(CMAKE_Swift_RESPONSE_FILE_LINK_FLAG @) set(CMAKE_Swift_RESPONSE_FILE_FLAG @) set(CMAKE_Swift_COMPILE_OPTIONS_COLOR_DIAGNOSTICS -color-diagnostics) set(CMAKE_Swift_COMPILE_OPTIONS_COLOR_DIAGNOSTICS_OFF -no-color-diagnostics) +set(CMAKE_Swift_PACKAGE_NAME_FLAG -package-name) set(CMAKE_Swift_LINKER_PREFERENCE 50) set(CMAKE_Swift_LINKER_PREFERENCE_PROPAGATES 1) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 73016f4792..eabb792b2d 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -2820,6 +2820,22 @@ void cmGeneratorTarget::AddSwiftTargetFlags(std::string& flags) const flags += " -swift-version " + *version; } } + + if (!this->GetGlobalGenerator()->IsXcode() && + cmSystemTools::VersionCompare( + cmSystemTools::OP_GREATER_EQUAL, + this->Makefile->GetDefinition("CMAKE_Swift_COMPILER_VERSION"), + "5.8")) { + // Note: The Xcode generator sets the `SWIFT_PACKAGE_NAME` BuildSettings + // attribute + std::string const packageName = this->GetSwiftPackageName(); + if (!packageName.empty()) { + std::string const packageFlag = + this->Makefile->GetSafeDefinition("CMAKE_Swift_PACKAGE_NAME_FLAG"); + // Add the package name to the flags + flags += " " + packageFlag + " " + packageName; + } + } } void cmGeneratorTarget::AddCUDAToolkitFlags(std::string& flags) const @@ -6183,6 +6199,15 @@ std::string cmGeneratorTarget::BuildDatabasePath( "_build_database.json"); } +std::string cmGeneratorTarget::GetSwiftPackageName() const +{ + std::string packageName; + if (cmValue projectName = this->GetProperty("Swift_PACKAGE_NAME")) { + packageName = *projectName; + } + return packageName; +} + std::string cmGeneratorTarget::GetSwiftModuleName() const { return this->GetPropertyOrDefault("Swift_MODULE_NAME", this->GetName()); diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index f641fc6b5c..23f59bc015 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -640,6 +640,9 @@ public: std::string GetClangTidyExportFixesDirectory(std::string const& lang) const; + /** Return the Swift package name for this target. */ + std::string GetSwiftPackageName() const; + /** Return the swift module name for this target. */ std::string GetSwiftModuleName() const; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index de19966136..1fedd91a34 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -2723,6 +2723,15 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, break; } } + + // Add SWIFT_PACKAGE_NAME + if (this->XcodeVersion >= 150) { + std::string const packageName = gtgt->GetSwiftPackageName(); + if (!packageName.empty()) { + buildSettings->AddAttribute("SWIFT_PACKAGE_NAME", + this->CreateString(packageName)); + } + } } std::string extraLinkOptions; diff --git a/Tests/RunCMake/Swift/PackageName-check.cmake b/Tests/RunCMake/Swift/PackageName-check.cmake new file mode 100644 index 0000000000..cc9177bc42 --- /dev/null +++ b/Tests/RunCMake/Swift/PackageName-check.cmake @@ -0,0 +1,27 @@ +if(RunCMake_GENERATOR MATCHES "Ninja") + if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(path "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/impl-Debug.ninja") + else() + set(path "${RunCMake_TEST_BINARY_DIR}/build.ninja") + endif() + file(READ "${path}" build_ninja) + + if(NOT build_ninja MATCHES "Swift_COMPILER__L1[^\n]*(\n [^\n]+)*\n FLAGS = [^\n]*-package-name SwiftPackageTest") + string(APPEND RunCMake_TEST_FAILED + "Expected L1 compile FLAGS to contain -package-name SwiftPackageTest\n") + endif() + + if(build_ninja MATCHES "Swift_COMPILER__L2[^\n]*(\n [^\n]+)*\n FLAGS = [^\n]*-package-name") + string(APPEND RunCMake_TEST_FAILED + "L2 compile FLAGS should not contain -package-name\n") + endif() + +elseif(RunCMake_GENERATOR MATCHES "Xcode") + file(READ + "${RunCMake_TEST_BINARY_DIR}/PackageName.xcodeproj/project.pbxproj" + pbxproj) + if(NOT pbxproj MATCHES "SWIFT_PACKAGE_NAME = SwiftPackageTest") + string(APPEND RunCMake_TEST_FAILED + "Expected SWIFT_PACKAGE_NAME = SwiftPackageTest in Xcode project for L1\n") + endif() +endif() diff --git a/Tests/RunCMake/Swift/PackageName.cmake b/Tests/RunCMake/Swift/PackageName.cmake new file mode 100644 index 0000000000..caf138b5f0 --- /dev/null +++ b/Tests/RunCMake/Swift/PackageName.cmake @@ -0,0 +1,13 @@ +cmake_policy(SET CMP0157 NEW) + +enable_language(Swift) + +add_library(L1 L.swift) +set_target_properties(L1 PROPERTIES + Swift_PACKAGE_NAME "SwiftPackageTest" +) + +add_library(L2 L.swift) +set_target_properties(L2 PROPERTIES + Swift_PACKAGE_NAME "" +) diff --git a/Tests/RunCMake/Swift/RunCMakeTest.cmake b/Tests/RunCMake/Swift/RunCMakeTest.cmake index 21f4f359e9..21669ae474 100644 --- a/Tests/RunCMake/Swift/RunCMakeTest.cmake +++ b/Tests/RunCMake/Swift/RunCMakeTest.cmake @@ -182,3 +182,8 @@ if(RunCMake_GENERATOR MATCHES "Ninja") run_cmake(CMP0214-OLD) run_cmake(CMP0214-NEW-CMP0157-OLD) endif() + +if(NOT RunCMake_GENERATOR STREQUAL "Xcode" OR + (RunCMake_GENERATOR STREQUAL "Xcode" AND XCODE_VERSION VERSION_GREATER_EQUAL 15.0)) + run_cmake(PackageName) +endif()