Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create script to automatically set CLANG_CXX_LANGUAGE_STANDARD on the client project #33863

Closed
wants to merge 7 commits into from
Closed
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
2 changes: 1 addition & 1 deletion React-Core.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 2 additions & 0 deletions packages/rn-tester/Podfile
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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
6 changes: 4 additions & 2 deletions packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -913,6 +913,7 @@
"-ObjC",
"-lc++",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../..";
SDKROOT = iphoneos;
WARNING_CFLAGS = (
"-Wextra",
Expand All @@ -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;
Expand Down Expand Up @@ -989,6 +990,7 @@
"-ObjC",
"-lc++",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../..";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
WARNING_CFLAGS = (
Expand Down
133 changes: 133 additions & 0 deletions scripts/cocoapods/__tests__/new_architecture-test.rb
Original file line number Diff line number Diff line change
@@ -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
36 changes: 35 additions & 1 deletion scripts/cocoapods/__tests__/test_utils/InstallerMock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -58,13 +60,45 @@ def initialize(targets = [])
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

Expand Down
30 changes: 30 additions & 0 deletions scripts/cocoapods/new_architecture.rb
Original file line number Diff line number Diff line change
@@ -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