blob: e9b506b1a8c9c3a522ace37c643e089b415589dc [file] [log] [blame]
# Copyright 2019 The Pigweed Authors
#
# 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
#
# https://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.
declare_args() {
# Sets the sanitizer to pass to clang. Valid values are those for "-fsanitize"
# listed in https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html.
pw_sanitizer = ""
# Indicates if this build is a part of OSS-Fuzz, which needs to be able to
# provide its own compiler and flags. This violates the build hermeticisim and
# should only be used for OSS-Fuzz.
oss_fuzz_enabled = false
}
# Generates a host clang toolchain for a specific target.
#
# Args:
# toolchain_cflags: Additional C/C++ compiler flags for the target.
# toolchain_ldflags: Additional linker flags for the target.
template("host_clang") {
# Toolchain C flags
_cflags_list = [
# Colorize output. Ninja's Clang invocation disables color by default.
"-fdiagnostics-color",
]
if (defined(invoker.toolchain_cflags)) {
_cflags_list += invoker.toolchain_cflags
}
if (host_os == "mac") {
_xcode_sysroot = exec_script("$dir_pw_build/py/exec.py",
[
"--",
"/usr/bin/xcrun",
"--show-sdk-path",
],
"trim string")
_cflags_list += [ "--sysroot=$_xcode_sysroot" ]
}
_cflags_c_list = []
# Toolchain C++ flags
_cflags_cc_list = [
# Specify the default C++ version, which targets can override with a config.
"-std=c++17",
"-Wno-register",
]
# Toolchain LD flags
_ldflags_list = []
if (defined(invoker.toolchain_ldflags)) {
_ldflags_list += invoker.toolchain_ldflags
}
if (host_os == "mac") {
# The CIPD provided Clang/LLVM toolchain must link against the matched
# libc++ which is also from CIPD. However, by default, Clang on Mac (but
# not on Linux) will fall back to the system libc++, which is
# incompatible due to an ABI change.
#
# Pull the appropriate path from our Pigweed env setup.
assert(getenv("PW_PIGWEED_CIPD_INSTALL_DIR") != "",
"You forgot to activate the Pigweed environment; " +
"did you source pw_env_setup/setup.sh?")
_ldflags_list += [
# Force dropping the system libc++
"-nostdlib++",
# Use the libc++ from CIPD.
getenv("PW_PIGWEED_CIPD_INSTALL_DIR") + "/lib/libc++.a",
]
}
# Note: On macOS, there is no "llvm-ar", only "ar", which happens to be LLVM
# ar. This should get updated for linux systems.
_ar = "ar"
_cc = "clang"
_cxx = "clang++"
# OSS-Fuzz needs to be able to specify its own compilers and add flags.
if (oss_fuzz_enabled) {
_cc = getenv("CC")
_cxx = getenv("CXX")
_cflags_c_list += string_split(getenv("CFLAGS"))
_cflags_cc_list += string_split(getenv("CXXFLAGS"))
_ldflags_list += string_split(getenv("CXXFLAGS"))
# TODO(pwbug/184): OSS-Fuzz sets -stdlib=libc++, but pw_minimal_cpp_stdlib
# sets -nostdinc++. Find a more flexible mechanism to achieve this and
# similar needs (like removing -fno-rtti fro UBSan).
_cflags_cc_list += [ "-Wno-unused-command-line-argument" ]
}
_toolchain_cflags = string_join(" ", _cflags_list)
_toolchain_cflags_c = string_join(" ", _cflags_c_list)
_toolchain_cflags_cc = string_join(" ", _cflags_cc_list)
_toolchain_ldflags = string_join(" ", _ldflags_list)
toolchain(target_name) {
tool("asm") {
depfile = "{{output}}.d"
command = string_join(" ",
[
"$_cc",
"-MMD -MF $depfile", # Write out dependencies.
_toolchain_cflags,
"{{defines}}",
"{{include_dirs}}",
"{{asmflags}}",
"-c {{source}}",
"-o {{output}}",
])
depsformat = "gcc"
description = "as {{output}}"
outputs = [
# Use {{source_file_part}}, which includes the extension, instead of
# {{source_name_part}} so that object files created from <file_name>.c
# and <file_name>.cc sources are unique.
"{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o",
]
}
tool("cc") {
depfile = "{{output}}.d"
command = string_join(" ",
[
"$_cc",
"-MMD -MF $depfile", # Write out dependencies.
_toolchain_cflags_c,
_toolchain_cflags,
"{{defines}}",
"{{include_dirs}}",
"{{cflags}}",
"{{cflags_c}}",
"-c {{source}}",
"-o {{output}}",
])
depsformat = "gcc"
description = "cc {{output}}"
outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o" ]
}
tool("cxx") {
depfile = "{{output}}.d"
command = string_join(" ",
[
"$_cxx",
"-MMD -MF $depfile", # Write out dependencies.
_toolchain_cflags_cc,
_toolchain_cflags,
"{{defines}}",
"{{include_dirs}}",
"{{cflags}}",
"{{cflags_cc}}",
"-c {{source}}",
"-o {{output}}",
])
depsformat = "gcc"
description = "c++ {{output}}"
outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_file_part}}.o" ]
}
tool("alink") {
command = "rm -f {{output}} && $_ar rcs {{output}} {{inputs}}"
description = "ar {{target_output_name}}{{output_extension}}"
outputs =
[ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
default_output_extension = ".a"
}
lib_switch = "-l"
lib_dir_switch = "-L"
_link_outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
_link_flags = [
"$_cxx",
"{{ldflags}}",
_toolchain_ldflags,
_toolchain_cflags,
"{{inputs}}",
"{{libs}}",
"-o $_link_outfile",
]
_link_mapfile = "{{output_dir}}/{{target_output_name}}.map"
if (host_os == "mac") {
_link_flags += [
# Output a map file that shows symbols and their location.
"-Wl,-map,$_link_mapfile",
# Delete unreferenced sections. Helpful with -ffunction-sections.
"-Wl,-dead_strip",
]
} else {
_link_flags += [
# Output a map file that shows symbols and their location.
"-Wl,-Map,$_link_mapfile",
# Delete unreferenced sections. Helpful with -ffunction-sections.
"-Wl,--gc-sections",
]
}
_link_command = string_join(" ", _link_flags)
tool("link") {
command = _link_command
description = "ld $_link_outfile"
outputs = [ _link_outfile ]
default_output_dir = "{{target_out_dir}}"
if (host_os == "win") {
default_output_extension = ".exe"
} else {
default_output_extension = ""
}
}
tool("solink") {
command = _link_command + " -shared"
description = "ld -shared $_link_outfile"
outputs = [ _link_outfile ]
default_output_dir = "{{target_out_dir}}"
default_output_extension = ".so"
}
tool("stamp") {
if (host_os == "win") {
command = "cmd /c type nul > \"{{output}}\""
} else {
command = "touch {{output}}"
}
description = "stamp {{output}}"
}
tool("copy") {
command = "cp -af {{source}} {{output}}"
description = "cp {{source}} {{output}}"
}
}
}