1# Copyright 2019 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import("//build/config/ios/deployment_target.gni")
6
7declare_args() {
8  # Configure whether whole module optimization is enabled when compiling
9  # swift modules.
10  swift_whole_module_optimization = true
11}
12
13template("ios_toolchain") {
14  toolchain(target_name) {
15    assert(defined(invoker.toolchain_args),
16           "Toolchains must declare toolchain_args")
17
18    toolchain_args = {
19      forward_variables_from(invoker.toolchain_args, "*")
20    }
21
22    _sdk_info = exec_script("//build/config/ios/scripts/sdk_info.py",
23                            [
24                              "--target-cpu",
25                              current_cpu,
26                              "--target-environment",
27                              target_environment,
28                              "--deployment-target",
29                              ios_deployment_target,
30                            ],
31                            "json")
32
33    cc = "clang -target ${_sdk_info.target} -isysroot ${_sdk_info.sdk_path}"
34    cxx = "clang++ -target ${_sdk_info.target} -isysroot ${_sdk_info.sdk_path}"
35
36    swiftmodule_switch = "-Wl,-add_ast_path,"
37
38    tool("link") {
39      output = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
40      rspfile = output + ".rsp"
41      rspfile_content = "{{inputs_newline}}"
42
43      outputs = [ output ]
44      command = "$cxx {{ldflags}} -o $output -Wl,-filelist,$rspfile {{libs}} {{solibs}} {{frameworks}} {{swiftmodules}}"
45      description = "LINK {{output}}"
46
47      default_output_dir = "{{root_out_dir}}"
48      default_output_extension = ""
49      output_prefix = ""
50    }
51
52    tool("solink") {
53      dylib = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
54      rspfile = dylib + ".rsp"
55      rspfile_content = "{{inputs_newline}}"
56
57      outputs = [ dylib ]
58      command = "$cxx -dynamiclib {{ldflags}} -o $dylib -Wl,-filelist,$rspfile {{libs}} {{solibs}} {{frameworks}} {{swiftmodules}}"
59      description = "SOLINK {{output}}"
60
61      default_output_dir = "{{root_out_dir}}"
62      default_output_extension = ".dylib"
63      output_prefix = "lib"
64    }
65
66    tool("cc") {
67      depfile = "{{output}}.d"
68      precompiled_header_type = "gcc"
69      command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
70      depsformat = "gcc"
71      description = "CC {{output}}"
72      outputs = [ "{{target_out_dir}}/{{label_name}}/{{source_name_part}}.o" ]
73    }
74
75    tool("cxx") {
76      depfile = "{{output}}.d"
77      precompiled_header_type = "gcc"
78      command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
79      depsformat = "gcc"
80      description = "CXX {{output}}"
81      outputs = [ "{{target_out_dir}}/{{label_name}}/{{source_name_part}}.o" ]
82    }
83
84    tool("objc") {
85      depfile = "{{output}}.d"
86      precompiled_header_type = "gcc"
87      command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_objc}} -c {{source}} -o {{output}}"
88      depsformat = "gcc"
89      description = "OBJC {{output}}"
90      outputs = [ "{{target_out_dir}}/{{label_name}}/{{source_name_part}}.o" ]
91    }
92
93    tool("objcxx") {
94      depfile = "{{output}}.d"
95      precompiled_header_type = "gcc"
96      command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_objcc}} -c {{source}} -o {{output}}"
97      depsformat = "gcc"
98      description = "OBJCXX {{output}}"
99      outputs = [ "{{target_out_dir}}/{{label_name}}/{{source_name_part}}.o" ]
100    }
101
102    tool("stamp") {
103      command = "touch {{output}}"
104      description = "STAMP {{output}}"
105    }
106
107    tool("copy_bundle_data") {
108      command = "rm -rf {{output}} && cp -PR {{source}} {{output}}"
109      description = "COPY_BUNDLE_DATA {{output}}"
110    }
111
112    tool("swift") {
113      depfile = "{{target_out_dir}}/{{module_name}}.d"
114      depsformat = "gcc"
115
116      outputs = [
117        # The module needs to be the first output to ensure the
118        # depfile generate works correctly with ninja < 1.9.0.
119        "{{target_gen_dir}}/{{module_name}}.swiftmodule",
120
121        "{{target_gen_dir}}/{{module_name}}.h",
122        "{{target_gen_dir}}/{{module_name}}.swiftdoc",
123        "{{target_gen_dir}}/{{module_name}}.swiftsourceinfo",
124      ]
125
126      if (swift_whole_module_optimization) {
127        _extra_flag = "--whole-module-optimization"
128        _object_dir = "{{target_out_dir}}"
129        outputs += [ "{{target_out_dir}}/{{module_name}}.o" ]
130      } else {
131        _extra_flag = ""
132        _object_dir = "{{target_out_dir}}/{{label_name}}"
133        partial_outputs =
134            [ "{{target_out_dir}}/{{label_name}}/{{source_name_part}}.o" ]
135      }
136
137      _swiftc = rebase_path("//build/toolchain/apple/swiftc.py", root_build_dir)
138      command = "$_swiftc --target ${_sdk_info.target} --sdk ${_sdk_info.sdk_path} --module-name {{module_name}} --object-dir $_object_dir --module-path {{target_gen_dir}}/{{module_name}}.swiftmodule --header-path {{target_gen_dir}}/{{module_name}}.h --depfile {{target_out_dir}}/{{module_name}}.d --depfile-filter {{target_gen_dir}}/{{module_name}}.swiftmodule --bridge-header {{bridge_header}} $_extra_flag {{defines}} {{swiftflags}} {{include_dirs}} {{module_dirs}} {{inputs}}"
139    }
140  }
141}
142
143ios_toolchain("clang_x86") {
144  toolchain_args = {
145    current_cpu = "x86"
146    current_os = "ios"
147  }
148}
149
150ios_toolchain("clang_x64") {
151  toolchain_args = {
152    current_cpu = "x64"
153    current_os = "ios"
154  }
155}
156
157ios_toolchain("clang_arm") {
158  toolchain_args = {
159    current_cpu = "arm"
160    current_os = "ios"
161  }
162}
163
164ios_toolchain("clang_arm64") {
165  toolchain_args = {
166    current_cpu = "arm64"
167    current_os = "ios"
168  }
169}
170