SERVER-98714 add custom macos toolchain for bazel (#30578)

GitOrigin-RevId: 2932fa230db8a6f62949e1fb365c78399ff0b9d1
This commit is contained in:
Daniel Moody 2024-12-20 21:32:25 -06:00 committed by MongoDB Bot
parent b036d405f0
commit b2f97d9c0c
16 changed files with 3299 additions and 38 deletions

View File

@ -21,6 +21,8 @@ build --experimental_cc_shared_library
# Reuse sandboxes to save sandbox execution and deletion times.
build --experimental_reuse_sandbox_directories
build:macos --repo_env=BAZEL_NO_APPLE_CPP_TOOLCHAIN=1
# while in hybrid build state, using local unsandboxed linking should be faster. When most of our link
# targets have been converted (i.e. unittest binaries) and we can BWOB, remote linking should be faster
# in those cases:

View File

@ -19,8 +19,6 @@ load("@bazel_features//:deps.bzl", "bazel_features_deps")
bazel_features_deps()
load("//bazel/platforms:local_config_platform.bzl", "setup_local_config_platform")
http_archive(
name = "bazel_clang_tidy",
sha256 = "f77f7f63fc43b6f7dba23f807132e24c36110d481826685ce49f38a04058c4ea",
@ -36,10 +34,21 @@ http_archive(
],
)
load("//bazel/platforms:local_config_platform.bzl", "setup_local_config_platform")
load("//bazel/toolchains:mongo_toolchain.bzl", "toolchain_download")
setup_local_config_platform(name = "internal_platforms_do_not_use")
setup_mongo_toolchains()
load("//bazel/toolchains/mongo_apple:mongo_apple_toolchain.bzl", "mongo_apple_toolchain_config", "mongo_apple_toolchain_setup")
mongo_apple_toolchain_config(name = "mongo_apple_toolchain_config")
mongo_apple_toolchain_setup(name = "mongo_apple_toolchain")
register_toolchains("@mongo_apple_toolchain//...")
http_archive(
name = "windows_sasl",
build_file_content = """

View File

@ -28,6 +28,7 @@ load(
"opt",
"pgo_profile",
"release",
"sdkroot",
"separate_debug",
"server_js",
"shared_archive",
@ -1736,6 +1737,14 @@ config_setting(
},
)
selects.config_setting_group(
name = "build_enterprise_linux_enabled",
match_all = [
":build_enterprise_enabled",
"@platforms//os:linux",
],
)
# --------------------------------------
# stream_release_build
# --------------------------------------
@ -2154,6 +2163,15 @@ developer_dir(
build_setting_default = "/Applications/Xcode.app",
)
# --------------------------------------
# sdkroot
# --------------------------------------
sdkroot(
name = "sdkroot",
build_setting_default = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk",
)
# --------------------------------------
# js_engine options
# --------------------------------------

View File

@ -606,6 +606,20 @@ developer_dir = rule(
build_setting = config.string(flag = True),
)
# =============
# sdkroot
# =============
sdkroot_provider = provider(
doc = "The path to the sdk, e.g. SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk",
fields = {"path": "sdk root.]"},
)
sdkroot = rule(
implementation = lambda ctx: sdkroot_provider(path = ctx.build_setting_value),
build_setting = config.string(flag = True),
)
# =========
# js_engine
# =========

View File

@ -1,6 +1,6 @@
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
load("//bazel/config:configs.bzl", "developer_dir_provider")
load("//bazel/config:configs.bzl", "developer_dir_provider", "sdkroot_provider")
load("//bazel:mongo_src_rules.bzl", "write_target")
def generate_config_header_impl(ctx):
@ -72,7 +72,6 @@ def generate_config_header_impl(ctx):
ctx.attr.template.files,
ctx.attr.checks.files,
] + additional_inputs_depsets),
env = {"DEVELOPER_DIR": ctx.attr._developer_dir[developer_dir_provider].path},
arguments = [
generator_script, # bazel/config/mongo_config_header.py
"--output-path",
@ -93,7 +92,7 @@ def generate_config_header_impl(ctx):
"--compiler-args",
" ".join(compiler_flags),
"--env-vars",
json.encode(env_flags),
json.encode(env_flags | {"DEVELOPER_DIR": ctx.attr._developer_dir[developer_dir_provider].path, "SDKROOT": ctx.attr._sdkroot[sdkroot_provider].path}),
],
)
@ -142,6 +141,7 @@ generate_config_header_rule = rule(
),
"_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
"_developer_dir": attr.label(default = "//bazel/config:developer_dir"),
"_sdkroot": attr.label(default = "//bazel/config:sdkroot"),
},
fragments = ["cpp"],
toolchains = ["@bazel_tools//tools/cpp:toolchain_type", "@bazel_tools//tools/python:toolchain_type"],

View File

@ -1274,14 +1274,6 @@ PGO_PROFILE_FLAGS = select({
"//conditions:default": [],
})
MACOS_SSL_LINKFLAGS = select({
"//bazel/config:ssl_enabled_macos": [
"-framework CoreFoundation",
"-framework Security",
],
"//conditions:default": [],
})
MONGO_GLOBAL_INCLUDE_DIRECTORIES = [
"-Isrc",
"-I$(GENDIR)/src",
@ -1379,7 +1371,6 @@ MONGO_GLOBAL_LINKFLAGS = (
COVERAGE_FLAGS +
GLOBAL_WINDOWS_LIBRAY_LINKFLAGS +
SASL_WINDOWS_LINKFLAGS +
MACOS_SSL_LINKFLAGS +
PGO_PROFILE_FLAGS +
SANITIZE_WITHOUT_TSAN_LINKFLAGS
)

View File

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
load("@build_bazel_apple_support//configs:platforms.bzl", "APPLE_PLATFORMS_CONSTRAINTS")
load("@//bazel/toolchains/mongo_apple:mongo_apple_toolchain.bzl", "get_supported_apple_archs")
package(default_visibility = ["//visibility:public"])
[
toolchain(
name = "mongo_apple_" + apple_arch + " _toolchain",
exec_compatible_with = [
"@platforms//os:macos",
"@platforms//cpu:" + cpu,
],
target_compatible_with = [
"@platforms//os:macos",
"@platforms//cpu:" + cpu,
],
toolchain = "@mongo_apple_toolchain_config//:cc-compiler-" + apple_arch,
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
for apple_arch, cpu in get_supported_apple_archs().items()
]

View File

@ -0,0 +1,341 @@
# pylint: disable=g-bad-file-header
# Copyright 2016 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.
"""Configuring the C++ toolchain on macOS."""
load(
"@bazel_tools//tools/cpp:lib_cc_configure.bzl",
"escape_string",
)
load("@bazel_tools//tools/osx:xcode_configure.bzl", "run_xcode_locator")
###
# mongodb customization
load("@build_bazel_apple_support//configs:platforms.bzl", "APPLE_PLATFORMS_CONSTRAINTS")
load("//bazel/platforms:normalize.bzl", "ARCH_NORMALIZE_MAP")
###
_DISABLE_ENV_VAR = "BAZEL_NO_APPLE_CPP_TOOLCHAIN"
_OLD_DISABLE_ENV_VAR = "BAZEL_USE_CPP_ONLY_TOOLCHAIN"
def _get_escaped_xcode_cxx_inc_directories(repository_ctx, xcode_toolchains):
"""Compute the list of default C++ include paths on Xcode-enabled darwin.
Args:
repository_ctx: The repository context.
xcode_toolchains: A list containing the xcode toolchains available
Returns:
include_paths: A list of builtin include paths.
"""
# Assume that everything is managed by Xcode / toolchain installations
include_dirs = [
"/Applications/",
"/Library/",
]
user = repository_ctx.os.environ.get("USER")
if user:
include_dirs.extend([
"/Users/{}/Applications/".format(user),
"/Users/{}/Library/".format(user),
])
# Include extra Xcode paths in case they're installed on other volumes
for toolchain in xcode_toolchains:
include_dirs.append(escape_string(toolchain.developer_dir))
return include_dirs
def _succeeds(repository_ctx, *args):
env = repository_ctx.os.environ
result = repository_ctx.execute([
"env",
"-i",
"DEVELOPER_DIR={}".format(env.get("DEVELOPER_DIR", default = "")),
"xcrun",
"--sdk",
"macosx",
] + list(args))
return result.return_code == 0
def _generate_system_modulemap(repository_ctx, script, output):
env = repository_ctx.os.environ
result = repository_ctx.execute([
"env",
"-i",
"DEVELOPER_DIR={}".format(env.get("DEVELOPER_DIR", default = "")),
script,
])
if result.return_code != 0:
error_msg = (
"return code {code}, stderr: {err}, stdout: {out}"
).format(
code = result.return_code,
err = result.stderr,
out = result.stdout,
)
fail(output + " failed to generate. Please file an issue at " +
"https://github.com/bazelbuild/apple_support/issues with the following:\n" +
error_msg)
repository_ctx.file(output, result.stdout)
def _compile_cc_file(repository_ctx, src_name, out_name):
env = repository_ctx.os.environ
xcrun_result = repository_ctx.execute([
"env",
"-i",
"DEVELOPER_DIR={}".format(env.get("DEVELOPER_DIR", default = "")),
"xcrun",
"--sdk",
"macosx",
"clang",
"-mmacosx-version-min=10.15",
"-std=c++17",
"-lc++",
"-arch",
"arm64",
"-arch",
"x86_64",
"-Wl,-no_adhoc_codesign",
"-Wl,-no_uuid",
"-O3",
"-o",
out_name,
src_name,
])
if xcrun_result.return_code != 0:
error_msg = (
"return code {code}, stderr: {err}, stdout: {out}"
).format(
code = xcrun_result.return_code,
err = xcrun_result.stderr,
out = xcrun_result.stdout,
)
fail(out_name + " failed to generate. Please file an issue at " +
"https://github.com/bazelbuild/apple_support/issues with the following:\n" +
error_msg)
xcrun_result = repository_ctx.execute([
"env",
"-i",
"codesign",
"--identifier", # Required to be reproducible across archs
out_name,
"--force",
"--sign",
"-",
out_name,
])
if xcrun_result.return_code != 0:
error_msg = (
"codesign return code {code}, stderr: {err}, stdout: {out}"
).format(
code = xcrun_result.return_code,
err = xcrun_result.stderr,
out = xcrun_result.stdout,
)
fail(out_name + " failed to generate. Please file an issue at " +
"https://github.com/bazelbuild/apple_support/issues with the following:\n" +
error_msg)
def configure_osx_toolchain(repository_ctx):
"""Configure C++ toolchain on macOS.
Args:
repository_ctx: The repository context.
Returns:
Whether or not configuration was successful
"""
# All Label resolutions done at the top of the function to avoid issues
# with starlark function restarts, see this:
# https://github.com/bazelbuild/bazel/blob/ab71a1002c9c53a8061336e40f91204a2a32c38e/tools/cpp/lib_cc_configure.bzl#L17-L38
# for more info
xcode_locator = Label("@bazel_tools//tools/osx:xcode_locator.m")
osx_cc_wrapper = Label("@bazel_tools//tools/cpp:osx_cc_wrapper.sh.tpl")
xcrunwrapper = Label("@build_bazel_apple_support//crosstool:xcrunwrapper.sh")
libtool = Label("@build_bazel_apple_support//crosstool:libtool.sh")
make_hashed_objlist = Label("@build_bazel_apple_support//crosstool:make_hashed_objlist.py")
###
# mongodb customization
cc_toolchain_config = Label("@//bazel/toolchains/mongo_apple:mongo_apple_cc_toolchain_config.bzl")
###
build_template = Label("@build_bazel_apple_support//crosstool:BUILD.tpl")
libtool_check_unique_src_path = str(repository_ctx.path(
Label("@build_bazel_apple_support//crosstool:libtool_check_unique.cc"),
))
wrapped_clang_src_path = str(repository_ctx.path(
Label("@build_bazel_apple_support//crosstool:wrapped_clang.cc"),
))
generate_modulemap_path = str(repository_ctx.path(
Label("@build_bazel_apple_support//crosstool:generate-modulemap.sh"),
))
xcode_toolchains = []
xcodeloc_err = ""
allow_non_applications_xcode = "BAZEL_ALLOW_NON_APPLICATIONS_XCODE" in repository_ctx.os.environ and repository_ctx.os.environ["BAZEL_ALLOW_NON_APPLICATIONS_XCODE"] == "1"
if allow_non_applications_xcode:
(xcode_toolchains, xcodeloc_err) = run_xcode_locator(repository_ctx, xcode_locator)
if not xcode_toolchains:
return False, xcodeloc_err
# For Xcode toolchains, there's no reason to use anything other than
# wrapped_clang, so that we still get the Bazel Xcode placeholder
# substitution and other behavior for actions that invoke this
# cc_wrapper.sh script. The wrapped_clang binary is already hardcoded
# into the Objective-C crosstool actions, anyway, so this ensures that
# the C++ actions behave consistently.
cc_path = '"$(/usr/bin/dirname "$0")"/wrapped_clang'
###
# mongodb customization
# pass through cc_wrapper script
repository_ctx.file(
"cc_wrapper.sh",
"""
#!/bin/sh
%s $@
exit $?
""" % cc_path,
executable = True,
)
###
repository_ctx.symlink(xcrunwrapper, "xcrunwrapper.sh")
repository_ctx.symlink(libtool, "libtool")
repository_ctx.symlink(make_hashed_objlist, "make_hashed_objlist.py")
repository_ctx.symlink(cc_toolchain_config, "cc_toolchain_config.bzl")
_compile_cc_file(repository_ctx, libtool_check_unique_src_path, "libtool_check_unique")
_compile_cc_file(repository_ctx, wrapped_clang_src_path, "wrapped_clang")
repository_ctx.symlink("wrapped_clang", "wrapped_clang_pp")
layering_check_modulemap = None
if repository_ctx.os.environ.get("APPLE_SUPPORT_LAYERING_CHECK_BETA") == "1":
layering_check_modulemap = "layering_check.modulemap"
_generate_system_modulemap(repository_ctx, generate_modulemap_path, layering_check_modulemap)
repository_ctx.file(
"module.modulemap",
"// Placeholder to satisfy API requirements. See apple_support for usage",
)
tool_paths = {}
gcov_path = repository_ctx.os.environ.get("GCOV")
if gcov_path != None:
if not gcov_path.startswith("/"):
gcov_path = repository_ctx.which(gcov_path)
tool_paths["gcov"] = gcov_path
###
# mongodb customization
tool_paths["gcc"] = "wrapped_clang"
#
features = []
if _succeeds(repository_ctx, "ld", "-no_warn_duplicate_libraries", "-v"):
features.append("no_warn_duplicate_libraries")
escaped_include_paths = _get_escaped_xcode_cxx_inc_directories(repository_ctx, xcode_toolchains)
escaped_cxx_include_directories = []
for path in escaped_include_paths:
escaped_cxx_include_directories.append((" \"%s\"," % path))
if xcodeloc_err:
escaped_cxx_include_directories.append(" # Error: " + xcodeloc_err)
repository_ctx.template(
"BUILD",
build_template,
{
"%{cxx_builtin_include_directories}": "\n".join(escaped_cxx_include_directories),
"%{features}": "\n".join(['"{}"'.format(x) for x in features]),
"%{layering_check_modulemap}": "\":{}\",".format(layering_check_modulemap) if layering_check_modulemap else "",
"%{placeholder_modulemap}": "\":module.modulemap\"" if layering_check_modulemap else "None",
"%{tool_paths_overrides}": ",\n ".join(
['"%s": "%s"' % (k, v) for k, v in tool_paths.items()],
),
},
)
return True, ""
######
# mongodb customization
# everything below is modifications for mongodb build
def _apple_cc_autoconf_impl(repository_ctx):
if repository_ctx.os.name.startswith("mac os"):
success, error = configure_osx_toolchain(repository_ctx)
if not success:
fail("Failed to configure Apple CC toolchain, if you only have the command line tools installed and not Xcode, you cannot use this toolchain. You should either remove it or temporarily set '{}=1' in the environment: {}".format(_DISABLE_ENV_VAR, error))
else:
repository_ctx.file("BUILD", "# Apple CC autoconfiguration was disabled because you're not on macOS")
mongo_apple_toolchain_config = repository_rule(
environ = [
_DISABLE_ENV_VAR,
_OLD_DISABLE_ENV_VAR,
"APPLE_SUPPORT_LAYERING_CHECK_BETA",
"BAZEL_ALLOW_NON_APPLICATIONS_XCODE", # Signals to configure_osx_toolchain that some Xcodes may live outside of /Applications and we need to probe further when detecting/configuring them.
"DEVELOPER_DIR", # Used for making sure we use the right Xcode for compiling toolchain binaries
"GCOV", # TODO: Remove this
"USE_CLANG_CL", # Kept as a hack for those who rely on this invaliding the toolchain
"USER", # Used to allow paths for custom toolchains to be used by C* compiles
"XCODE_VERSION", # Force re-computing the toolchain by including the current Xcode version info in an env var
],
implementation = _apple_cc_autoconf_impl,
configure = True,
)
_ARCH_MAP = {
"aarch64": "@platforms//cpu:arm64",
"x86_64": "@platforms//cpu:x86_64",
"ppc64le": "@platforms//cpu:ppc",
"s390x": "@platforms//cpu:s390x",
}
def get_supported_apple_archs():
_APPLE_ARCHS = APPLE_PLATFORMS_CONSTRAINTS.keys()
supported_archs = {}
for arch in APPLE_PLATFORMS_CONSTRAINTS.keys():
if arch.startswith("darwin_"):
cpu = arch.replace("darwin_", "")
if cpu in ["x86_64", "arm64"]:
supported_archs[arch] = cpu
return supported_archs
def _toolchain_setup(ctx):
ctx.template(
"BUILD.bazel",
ctx.attr.build_tpl,
)
return None
mongo_apple_toolchain_setup = repository_rule(
implementation = _toolchain_setup,
attrs = {
"arch": attr.string(
values = ["amd64", "aarch64", "amd64", "x86_64", "ppc64le", "s390x"],
doc = "Host architecture.",
),
"build_tpl": attr.label(
default = "//bazel/toolchains/mongo_apple:mongo_apple_toolchain.BUILD",
doc = "Label denoting the BUILD file template that get's installed in the repo.",
),
},
)

View File

@ -0,0 +1,32 @@
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
load(
"@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
"feature",
"flag_group",
"flag_set",
)
_OBJCPP_EXECUTABLE_ACTION_NAME = "objc++-executable"
_DYNAMIC_LINK_ACTIONS = [
ACTION_NAMES.cpp_link_dynamic_library,
ACTION_NAMES.cpp_link_executable,
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
ACTION_NAMES.objc_executable,
_OBJCPP_EXECUTABLE_ACTION_NAME,
]
mongo_frameworks_feature = feature(
name = "mongo_frameworks",
enabled = True,
flag_sets = [
flag_set(
actions = _DYNAMIC_LINK_ACTIONS,
flag_groups = [
flag_group(
flags = ["-framework", "CoreFoundation", "-framework", "Security"],
),
],
),
],
)

View File

@ -145,6 +145,7 @@ toolchain(
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
# This file group makes it possible to set the clang-tidy configuration setting:
# --@bazel_clang_tidy//:clang_tidy_executable=@mongo_toolchain//:clang_tidy
filegroup(

View File

@ -31,11 +31,6 @@ class HeaderDefinition:
self.value = value
def macos_get_sdk_path():
result = subprocess.run(["xcrun", "--show-sdk-path"], capture_output=True, text=True)
return result.stdout.strip()
def compile_check(source_text: str) -> bool:
temp = None
if platform.system() == "Windows":
@ -451,7 +446,6 @@ def generate_config_header(
CompilerSettings.compiler_args = compiler_args
CompilerSettings.env_vars = {
**json.loads(env_vars),
**({"SDKROOT": macos_get_sdk_path()} if platform.system() == "Darwin" else {}),
}
logfile_path = logpath

View File

@ -105,6 +105,7 @@ cc_library(
],
target_compatible_with = select({
"@platforms//os:windows": ["@platforms//:incompatible"],
"@platforms//os:macos": ["@platforms//:incompatible"],
"//conditions:default": [],
}),
deps = select({

View File

@ -40,23 +40,31 @@ def tool_to_path(tool, compiler_path):
return os.path.join(os.path.dirname(compiler_path), "g++")
elif os.path.basename(compiler_path) == "clang":
return os.path.join(os.path.dirname(compiler_path), "clang++")
elif os.path.basename(compiler_path) == "wrapped_clang":
return os.path.join(os.path.dirname(compiler_path), "wrapped_clang_pp")
else:
return
def get_toolchain_ver(tool, compiler_path):
def get_toolchain_ver(tool, compiler_path, env_vars):
# By default we don't know the version of each tool, and only report what
# command gets executed (gcc vs /opt/mongodbtoolchain/bin/gcc).
verstr = "version unknown"
proc = None
tool = tool_to_path(tool, compiler_path)
if compiler_path.endswith("gcc") or compiler_path.endswith("clang"):
if (
compiler_path.endswith("gcc")
or compiler_path.endswith("clang")
or compiler_path.endswith("wrapped_clang_pp")
or compiler_path.endswith("wrapped_clang")
):
proc = subprocess.run(
f"{tool} --version",
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
stdin=subprocess.DEVNULL,
universal_newlines=True,
env=env_vars,
check=True,
shell=True,
text=True,
@ -69,6 +77,7 @@ def get_toolchain_ver(tool, compiler_path):
stderr=subprocess.PIPE,
stdin=subprocess.DEVNULL,
universal_newlines=True,
env=env_vars,
check=True,
shell=True,
text=True,
@ -87,7 +96,7 @@ def get_toolchain_ver(tool, compiler_path):
# inVersion: <bool> : should it be included in --version output
# The `value` field will be passed through env.subst, so you can use any SCons variables you
# want to define them.
def default_buildinfo_environment_data(compiler_path, extra_definitions):
def default_buildinfo_environment_data(compiler_path, extra_definitions, env_vars):
data = (
(
"distmod",
@ -103,7 +112,7 @@ def default_buildinfo_environment_data(compiler_path, extra_definitions):
),
(
"cc",
get_toolchain_ver("CC", compiler_path),
get_toolchain_ver("CC", compiler_path, env_vars),
True,
False,
),
@ -115,7 +124,7 @@ def default_buildinfo_environment_data(compiler_path, extra_definitions):
),
(
"cxx",
get_toolchain_ver("CXX", compiler_path),
get_toolchain_ver("CXX", compiler_path, env_vars),
True,
False,
),
@ -195,7 +204,9 @@ def generate_config_header(
log_check("")
extra_definitions_dict = json.loads(extra_definitions)
buildInfoInitializer = fmt_build_info(
default_buildinfo_environment_data(compiler_path, extra_definitions_dict)
default_buildinfo_environment_data(
compiler_path, extra_definitions_dict, json.loads(env_vars)
)
)
# This generates a numeric representation of the version string so that

View File

@ -7,6 +7,8 @@ import platform
import subprocess
import threading
import os
import json
import tempfile
from typing import Dict
logfile_path: str = ""
@ -29,22 +31,48 @@ class HeaderDefinition:
def compile_check(source_text: str) -> bool:
command = [
CompilerSettings.compiler_path,
"-C", # only compile and assemble, don't link since we don't want to have to pass in all of the libs of the dependencies
"-E",
"-x",
"c++",
*CompilerSettings.compiler_args.split(" "),
"-",
]
log_check(" ".join(command + [source_text]))
result = subprocess.run(command, input=source_text, capture_output=True, text=True)
temp = None
if platform.system() == "Windows":
temp = tempfile.NamedTemporaryFile(suffix=".cpp", delete=False)
temp.write(source_text.encode())
temp.close()
command = [
CompilerSettings.compiler_path,
"/c", # only compile and assemble, don't link since we don't want to have to pass in all of the libs of the dependencies
temp.name,
*CompilerSettings.compiler_args.split(" "),
]
log_check(" ".join(command[:-1] + [source_text]))
result = subprocess.run(
command,
capture_output=True,
text=True,
env={**os.environ.copy(), **CompilerSettings.env_vars},
)
else:
command = [
CompilerSettings.compiler_path,
"-c", # only compile and assemble, don't link since we don't want to have to pass in all of the libs of the dependencies
"-x",
"c++",
*CompilerSettings.compiler_args.split(" "),
"-",
]
log_check(" ".join(command + [source_text]))
result = subprocess.run(
command,
input=source_text,
capture_output=True,
text=True,
env={**os.environ.copy(), **CompilerSettings.env_vars},
)
if result.returncode != 0:
log_check(f"stdout:\n{result.stdout}")
log_check(f"stderr:\n{result.stderr}")
log_check(f"Exit code:\n{result.returncode}")
log_check("--------------------------------------------------\n\n")
if temp:
os.unlink(temp.name)
return result.returncode == 0
@ -109,7 +137,9 @@ def generate_config_header(compiler_path, compiler_args, env_vars, logpath, addi
global logfile_path
CompilerSettings.compiler_path = compiler_path
CompilerSettings.compiler_args = compiler_args
CompilerSettings.env_vars = {
**json.loads(env_vars),
}
if platform.system() == "Linux":
CompilerSettings.compiler_args += " -D_GNU_SOURCE"