# 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. # Generates an arm-eabi-none gcc 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("arm_gcc_toolchain") { _cflags_list = [ # Colorize output. Ninja's GCC invocation disables color by default. "-fdiagnostics-color", # Disable obnoxious ABI warning. # # GCC 7.1 adds an over-zealous ABI warning with little useful information # on how to resolve the issue. The warning you get is: # # note: parameter passing for argument of type '...' changed in GCC 7.1 # # There is no other information, and searching for the error is needed to # understand what is happening. For upstream Pigweed, we compile from # source so this is irrelevant; so disable it. # # See: https://gcc.gnu.org/gcc-7/changes.html (search for "psabi"). # https://gcc.gnu.org/ml/gcc/2017-05/msg00073.html "-Wno-psabi", ] if (defined(invoker.toolchain_cflags)) { _cflags_list += invoker.toolchain_cflags } _toolchain_cflags = string_join(" ", _cflags_list) # Specify the default C++ version, which targets can override with a config. _toolchain_cflags_cc = "-std=c++17 -Wno-register" _toolchain_ldflags = "" if (defined(invoker.toolchain_ldflags)) { _toolchain_ldflags += string_join(" ", invoker.toolchain_ldflags) } # TODO(frolv): This assumes that the ARM gcc toolchain is in the PATH. # It should be updated to point to the prebuilt path within the source tree # once that is added. _tool_name_root = "arm-none-eabi-" _ar = _tool_name_root + "ar" _cc = _tool_name_root + "gcc" _cxx = _tool_name_root + "g++" 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 .c # and .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, "{{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(" ", [ _cc, "-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_mapfile = "{{output_dir}}/{{target_output_name}}.map" _link_command = string_join( " ", [ _cxx, "{{ldflags}}", # Delete unreferenced sections. Helpful with -ffunction-sections. "-Wl,--gc-sections", # Output a map file that shows symbols and their location. "-Wl,-Map=$_link_mapfile", _toolchain_cflags, _toolchain_ldflags, "{{inputs}}", # Load all object files from all libraries to resolve symbols. # Short of living in the ideal world where all dependency graphs # among static libs are acyclic and all developers diligently # express such graphs in terms that GN understands, this is the # safest option. # Make sure you use this with --gc-sections, otherwise the # resulting binary will contain every symbol defined in every # input file and every static library. That could be quite a lot. "-Wl,--whole-archive", "{{libs}}", "-Wl,--no-whole-archive", "-o $_link_outfile", ]) tool("link") { command = _link_command description = "ld $_link_outfile" outputs = [ _link_outfile, ] default_output_dir = "{{target_out_dir}}" default_output_extension = ".elf" } 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") { command = "touch {{output}}" description = "stamp {{output}}" } tool("copy") { command = "cp -af {{source}} {{output}}" description = "cp {{source}} {{output}}" } } }