| # 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}}" |
| } |
| } |
| } |