Skip to content

Commit

Permalink
Handle swift toolchain and platform placeholds in swift worker.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 462733373
  • Loading branch information
Googler authored and swiple-rules-gardener committed Jul 23, 2022
1 parent 47b4648 commit fc4c4c7
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 6 deletions.
12 changes: 12 additions & 0 deletions tools/common/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ cc_library(
],
)

cc_library(
name = "swift_substitutions",
srcs = ["swift_substitutions.cc"],
hdrs = ["swift_substitutions.h"],
deps = [
":bazel_substitutions",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/types:optional",
],
)

cc_library(
name = "temp_file",
hdrs = ["temp_file.h"],
Expand Down
65 changes: 65 additions & 0 deletions tools/common/swift_substitutions.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2021 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tools/common/swift_substitutions.h"

#include "absl/strings/str_replace.h"
#include "absl/strings/substitute.h"
#include "absl/types/optional.h"

namespace bazel_rules_swift {
namespace {
// Returns the value of the given environment variable, or nullopt if it wasn't
// set.
absl::optional<std::string> GetEnvironmentVariable(absl::string_view name) {
std::string null_terminated_name(name.data(), name.length());
char* env_value = getenv(null_terminated_name.c_str());
if (env_value == nullptr) {
return absl::nullopt;
}
return env_value;
}

} // namespace

SwiftPlaceholderSubstitutions::SwiftPlaceholderSubstitutions() {
if (absl::optional<std::string> swift_toolchain_override =
GetEnvironmentVariable("SWIFT_TOOLCHAIN_OVERRIDE");
swift_toolchain_override.has_value()) {
substitutions_[kSwiftToolchainDir] = *swift_toolchain_override;
} else {
substitutions_[kSwiftToolchainDir] =
"__BAZEL_XCODE_DEVELOPER_DIR__/Toolchains/XcodeDefault.xctoolchain";
}

if (absl::optional<std::string> swift_platform_override =
GetEnvironmentVariable("SWIFT_PLATFORM_OVERRIDE");
swift_platform_override.has_value()) {
substitutions_[kSwiftPlatformDir] = *swift_platform_override;
} else if (absl::optional<std::string> apple_sdk_platform =
GetEnvironmentVariable("APPLE_SDK_PLATFORM");
apple_sdk_platform.has_value()) {
substitutions_[kSwiftPlatformDir] =
absl::Substitute("__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/$0.platform",
*apple_sdk_platform);
}
}

bool SwiftPlaceholderSubstitutions::Apply(std::string& arg) {
// Order here matters. Swift substitutions must be applied first.
// They can produce bazel substitutions that require further substitution.
bool swift_changed = absl::StrReplaceAll(substitutions_, &arg) > 0;
return bazel_substitutions_.Apply(arg) > 0 || swift_changed;
}
} // namespace bazel_rules_swift
50 changes: 50 additions & 0 deletions tools/common/swift_substitutions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2021 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef THIRD_PARTY_BAZEL_RULES_RULES_SWIFT_TOOLS_COMMON_SWIFT_SUBSTITUTIONS_H_
#define THIRD_PARTY_BAZEL_RULES_RULES_SWIFT_TOOLS_COMMON_SWIFT_SUBSTITUTIONS_H_

#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "tools/common/bazel_substitutions.h"

namespace bazel_rules_swift {

// Manages the substitution of special Swift placeholder strings in command line
// arguments that are used to defer the determination of toolchain and platform
// paths until execution time.
class SwiftPlaceholderSubstitutions {
public:
SwiftPlaceholderSubstitutions();

// Applies any necessary substitutions to `arg` and returns true if this
// caused the string to change.
bool Apply(std::string &arg);

inline static constexpr absl::string_view kSwiftToolchainDir =
"__SWIFT_TOOLCHAIN_DIR__";
inline static constexpr absl::string_view kSwiftPlatformDir =
"__SWIFT_PLATFORM_DIR__";

private:
// A mapping from bazel substitutes to their values.
BazelPlaceholderSubstitutions bazel_substitutions_;

// A mapping from swift toolchain to their substituted values.
absl::flat_hash_map<std::string, std::string> substitutions_;
};

} // namespace bazel_rules_swift

#endif // THIRD_PARTY_BAZEL_RULES_RULES_SWIFT_TOOLS_COMMON_SWIFT_SUBSTITUTIONS_H_
2 changes: 1 addition & 1 deletion tools/worker/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ cc_library(
srcs = ["swift_runner.cc"],
hdrs = ["swift_runner.h"],
deps = [
"//tools/common:bazel_substitutions",
"//tools/common:file_system",
"//tools/common:process",
"//tools/common:swift_substitutions",
"//tools/common:temp_file",
"@com_google_absl//absl/strings",
],
Expand Down
4 changes: 2 additions & 2 deletions tools/worker/swift_runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "tools/common/bazel_substitutions.h"
#include "tools/common/file_system.h"
#include "tools/common/process.h"
#include "tools/common/swift_substitutions.h"
#include "tools/common/temp_file.h"

namespace bazel_rules_swift {
Expand Down Expand Up @@ -226,7 +226,7 @@ bool SwiftRunner::ProcessArgument(
// ensure that our defensive quoting kicks in if an argument contains a
// space, even if no other changes would have been made.
std::string new_arg(arg);
bool changed = bazel_placeholder_substitutions_.Apply(new_arg) ||
bool changed = swift_placeholder_substitutions_.Apply(new_arg) ||
absl::StrContains(new_arg, ' ');
consumer(new_arg);
return changed;
Expand Down
6 changes: 3 additions & 3 deletions tools/worker/swift_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <vector>

#include "absl/strings/string_view.h"
#include "tools/common/bazel_substitutions.h"
#include "tools/common/swift_substitutions.h"
#include "tools/common/temp_file.h"

namespace bazel_rules_swift {
Expand Down Expand Up @@ -108,8 +108,8 @@ class SwiftRunner {

// A mapping of Bazel placeholder strings to the actual paths that should be
// substituted for them. Supports Xcode resolution on Apple OSes.
bazel_rules_swift::BazelPlaceholderSubstitutions
bazel_placeholder_substitutions_;
bazel_rules_swift::SwiftPlaceholderSubstitutions
swift_placeholder_substitutions_;

// The arguments, post-substitution, passed to the spawner.
std::vector<std::string> args_;
Expand Down

0 comments on commit fc4c4c7

Please sign in to comment.