Create script to automatically set CLANG_CXX_LANGUAGE_STANDARD on the client project (#33863)
Summary: Currently this [section](https://reactnative.dev/docs/next/new-architecture-app-intro#ios-enable-c17-language-feature-support) of the Playbook tells us to set CLANG_CXX_LANGUAGE_STANDARD = "c++17" in the main app target for the new architecture to work. Would be nice to be able to automate that instead ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [iOS] [Added] - Cocoapods function to add the `CLANG_CXX_LANGUAGE_STANDARD` to all the targets if needed Pull Request resolved: https://github.com/facebook/react-native/pull/33863 Test Plan: I've created some unit tests for the newly added function. I've executed pod install and the ruby tests locally. Reviewed By: cipolleschi Differential Revision: D36484366 Pulled By: f-meloni fbshipit-source-id: 553b092e747bef11d82195619ae1058985fdc325
This commit is contained in:
Родитель
baada4e299
Коммит
ca8174e15f
|
@ -47,7 +47,7 @@ Pod::Spec.new do |s|
|
|||
s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags
|
||||
s.header_dir = "React"
|
||||
s.framework = "JavaScriptCore"
|
||||
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/RCT-Folly\" \"${PODS_ROOT}/Headers/Public/React-hermes\" \"${PODS_ROOT}/Headers/Public/hermes-engine\" \"${PODS_ROOT}/Headers/Public/FlipperKit\" \"$(PODS_ROOT)/Headers/Public/ReactCommon\" \"$(PODS_ROOT)/Headers/Public/React-RCTFabric\"", "DEFINES_MODULE" => "YES", "GCC_PREPROCESSOR_DEFINITIONS" => "RCT_METRO_PORT=${RCT_METRO_PORT}" }
|
||||
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/RCT-Folly\" \"${PODS_ROOT}/Headers/Public/React-hermes\" \"${PODS_ROOT}/Headers/Public/hermes-engine\" \"${PODS_ROOT}/Headers/Public/FlipperKit\" \"$(PODS_ROOT)/Headers/Public/ReactCommon\" \"$(PODS_ROOT)/Headers/Public/React-RCTFabric\"", "DEFINES_MODULE" => "YES", "GCC_PREPROCESSOR_DEFINITIONS" => "RCT_METRO_PORT=${RCT_METRO_PORT}", "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" }
|
||||
s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\""}
|
||||
s.default_subspec = "Default"
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
"scripts/cocoapods/codegen.rb",
|
||||
"scripts/cocoapods/fabric.rb",
|
||||
"scripts/cocoapods/flipper.rb",
|
||||
"scripts/cocoapods/new_architecture.rb",
|
||||
"scripts/react-native-xcode.sh",
|
||||
"sdks/hermes-engine",
|
||||
"sdks/hermesc",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require_relative '../../scripts/react_native_pods'
|
||||
require_relative '../../scripts/cocoapods/new_architecture'
|
||||
|
||||
source 'https://cdn.cocoapods.org/'
|
||||
platform :ios, '12.4'
|
||||
|
@ -65,4 +66,5 @@ end
|
|||
post_install do |installer|
|
||||
react_native_post_install(installer, @prefix_path)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
set_clang_cxx_language_standard_if_needed(installer)
|
||||
end
|
||||
|
|
|
@ -843,7 +843,7 @@
|
|||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
|
@ -913,6 +913,7 @@
|
|||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../..";
|
||||
SDKROOT = iphoneos;
|
||||
WARNING_CFLAGS = (
|
||||
"-Wextra",
|
||||
|
@ -927,7 +928,7 @@
|
|||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
|
@ -989,6 +990,7 @@
|
|||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../..";
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
WARNING_CFLAGS = (
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
require "test/unit"
|
||||
require_relative "../new_architecture.rb"
|
||||
require_relative "./test_utils/InstallerMock.rb"
|
||||
require_relative "./test_utils/PodMock.rb"
|
||||
|
||||
class NewArchitectureTests < Test::Unit::TestCase
|
||||
def setup
|
||||
File.enable_testing_mode!
|
||||
end
|
||||
|
||||
def teardown
|
||||
Pod::UI.reset()
|
||||
end
|
||||
|
||||
|
||||
def test_setClangCxxLanguageStandardIfNeeded_whenReactCoreIsPresent
|
||||
installer = prepare_mocked_installer_with_react_core
|
||||
set_clang_cxx_language_standard_if_needed(installer)
|
||||
|
||||
assert_equal(installer.aggregate_targets[0].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], "c++17")
|
||||
assert_equal(installer.aggregate_targets[1].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], "c++17")
|
||||
assert_equal(installer.pods_project.targets[1].received_resolved_build_setting_parameters, [ReceivedCommonResolvedBuildSettings.new("CLANG_CXX_LANGUAGE_STANDARD", true)])
|
||||
assert_equal(Pod::UI.collected_messages, ["Setting CLANG_CXX_LANGUAGE_STANDARD to c++17 on /test/path.xcproj", "Setting CLANG_CXX_LANGUAGE_STANDARD to c++17 on /test/path2.xcproj"])
|
||||
end
|
||||
|
||||
def test_setClangCxxLanguageStandardIfNeeded_whenReactCoreIsNotPresent
|
||||
installer = prepare_mocked_installer_without_react_core
|
||||
set_clang_cxx_language_standard_if_needed(installer)
|
||||
|
||||
assert_equal(installer.aggregate_targets[0].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], nil)
|
||||
assert_equal(installer.aggregate_targets[1].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], nil)
|
||||
assert_equal(installer.pods_project.targets[0].received_resolved_build_setting_parameters, [])
|
||||
assert_equal(Pod::UI.collected_messages, [])
|
||||
end
|
||||
|
||||
def test_setClangCxxLanguageStandardIfNeeded_whenThereAreDifferentValuesForLanguageStandard_takesTheFirstValue
|
||||
installer = prepare_mocked_installer_with_react_core_and_different_language_standards
|
||||
set_clang_cxx_language_standard_if_needed(installer)
|
||||
|
||||
assert_equal(installer.aggregate_targets[0].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], "c++17")
|
||||
assert_equal(installer.aggregate_targets[1].user_project.build_configurations[0].build_settings["CLANG_CXX_LANGUAGE_STANDARD"], "c++17")
|
||||
assert_equal(installer.pods_project.targets[1].received_resolved_build_setting_parameters, [ReceivedCommonResolvedBuildSettings.new("CLANG_CXX_LANGUAGE_STANDARD", true)])
|
||||
assert_equal(Pod::UI.collected_messages, ["Setting CLANG_CXX_LANGUAGE_STANDARD to c++17 on /test/path.xcproj", "Setting CLANG_CXX_LANGUAGE_STANDARD to c++17 on /test/path2.xcproj"])
|
||||
end
|
||||
end
|
||||
|
||||
def prepare_mocked_installer_with_react_core
|
||||
return InstallerMock.new(
|
||||
PodsProjectMock.new([
|
||||
TargetMock.new(
|
||||
"YogaKit",
|
||||
[
|
||||
BuildConfigurationMock.new("Debug"),
|
||||
BuildConfigurationMock.new("Release"),
|
||||
]
|
||||
),
|
||||
TargetMock.new(
|
||||
"React-Core",
|
||||
[
|
||||
BuildConfigurationMock.new("Debug", { "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" }),
|
||||
BuildConfigurationMock.new("Release", { "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" }),
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
[
|
||||
AggregatedProjectMock.new(
|
||||
UserProjectMock.new("/test/path.xcproj", [BuildConfigurationMock.new("Debug")])
|
||||
),
|
||||
AggregatedProjectMock.new(
|
||||
UserProjectMock.new("/test/path2.xcproj", [BuildConfigurationMock.new("Debug")])
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def prepare_mocked_installer_with_react_core_and_different_language_standards
|
||||
return InstallerMock.new(
|
||||
PodsProjectMock.new([
|
||||
TargetMock.new(
|
||||
"YogaKit",
|
||||
[
|
||||
BuildConfigurationMock.new("Debug"),
|
||||
BuildConfigurationMock.new("Release"),
|
||||
]
|
||||
),
|
||||
TargetMock.new(
|
||||
"React-Core",
|
||||
[
|
||||
BuildConfigurationMock.new("Debug", { "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" }),
|
||||
BuildConfigurationMock.new("Release", { "CLANG_CXX_LANGUAGE_STANDARD" => "new" }),
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
[
|
||||
AggregatedProjectMock.new(
|
||||
UserProjectMock.new("/test/path.xcproj", [BuildConfigurationMock.new("Debug")])
|
||||
),
|
||||
AggregatedProjectMock.new(
|
||||
UserProjectMock.new("/test/path2.xcproj", [BuildConfigurationMock.new("Debug")])
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def prepare_mocked_installer_without_react_core
|
||||
return InstallerMock.new(
|
||||
PodsProjectMock.new([
|
||||
TargetMock.new(
|
||||
"YogaKit",
|
||||
[
|
||||
BuildConfigurationMock.new("Debug"),
|
||||
BuildConfigurationMock.new("Release"),
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
[
|
||||
AggregatedProjectMock.new(
|
||||
UserProjectMock.new("/test/path.xcproj", [BuildConfigurationMock.new("Debug")])
|
||||
),
|
||||
AggregatedProjectMock.new(
|
||||
UserProjectMock.new("/test/path2.xcproj", [BuildConfigurationMock.new("Debug")])
|
||||
),
|
||||
]
|
||||
)
|
||||
end
|
|
@ -38,9 +38,11 @@
|
|||
|
||||
class InstallerMock
|
||||
attr_reader :pods_project
|
||||
attr_reader :aggregate_targets
|
||||
|
||||
def initialize(pods_project = PodsProjectMock.new)
|
||||
def initialize(pods_project = PodsProjectMock.new, aggregate_targets = [AggregatedProjectMock.new])
|
||||
@pods_project = pods_project
|
||||
@aggregate_targets = aggregate_targets
|
||||
end
|
||||
|
||||
def target_with_name(name)
|
||||
|
@ -58,13 +60,45 @@ class PodsProjectMock
|
|||
end
|
||||
end
|
||||
|
||||
class AggregatedProjectMock
|
||||
attr_reader :user_project
|
||||
|
||||
def initialize(user_project = UserProjectMock.new)
|
||||
@user_project = user_project
|
||||
end
|
||||
end
|
||||
|
||||
class UserProjectMock
|
||||
attr_reader :path
|
||||
attr_reader :build_configurations
|
||||
|
||||
def initialize(path = "/test/path.xcproj", build_configurations = [])
|
||||
@path = path
|
||||
@build_configurations = build_configurations
|
||||
end
|
||||
|
||||
def save()
|
||||
end
|
||||
end
|
||||
|
||||
ReceivedCommonResolvedBuildSettings = Struct.new(:key, :resolve_against_xcconfig)
|
||||
|
||||
class TargetMock
|
||||
attr_reader :name
|
||||
attr_reader :build_configurations
|
||||
|
||||
attr_reader :received_resolved_build_setting_parameters
|
||||
|
||||
def initialize(name, build_configurations = [])
|
||||
@name = name
|
||||
@build_configurations = build_configurations
|
||||
@received_resolved_build_setting_parameters = []
|
||||
end
|
||||
|
||||
def resolved_build_setting(key, resolve_against_xcconfig: false)
|
||||
received_resolved_build_setting_parameters.append(ReceivedCommonResolvedBuildSettings.new(key, resolve_against_xcconfig))
|
||||
|
||||
return {name: build_configurations[0].build_settings[key]}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
def set_clang_cxx_language_standard_if_needed(installer)
|
||||
language_standard = nil
|
||||
|
||||
installer.pods_project.targets.each do |target|
|
||||
if target.name == 'React-Core'
|
||||
language_standard = target.resolved_build_setting("CLANG_CXX_LANGUAGE_STANDARD", resolve_against_xcconfig: true).values[0]
|
||||
end
|
||||
end
|
||||
|
||||
unless language_standard.nil?
|
||||
projects = installer.aggregate_targets
|
||||
.map{ |t| t.user_project }
|
||||
.uniq{ |p| p.path }
|
||||
|
||||
projects.each do |project|
|
||||
Pod::UI.puts("Setting CLANG_CXX_LANGUAGE_STANDARD to #{ language_standard } on #{ project.path }")
|
||||
|
||||
project.build_configurations.each do |config|
|
||||
config.build_settings["CLANG_CXX_LANGUAGE_STANDARD"] = language_standard
|
||||
end
|
||||
|
||||
project.save()
|
||||
end
|
||||
end
|
||||
end
|
Загрузка…
Ссылка в новой задаче