Build performs a single package to executable Go build. It takes in a package name, an output path, and set of compile options and from that it manages the whole compilation process. The error value may be of type *MultiError. Callers will likely want to check for this case and print such errors in
(pkgName, outpath, tmpdir string, config *compileopts.Config)
| 98 | // The error value may be of type *MultiError. Callers will likely want to check |
| 99 | // for this case and print such errors individually. |
| 100 | func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildResult, error) { |
| 101 | // Read the build ID of the tinygo binary. |
| 102 | // Used as a cache key for package builds. |
| 103 | compilerBuildID, err := ReadBuildID() |
| 104 | if err != nil { |
| 105 | return BuildResult{}, err |
| 106 | } |
| 107 | |
| 108 | if config.Options.Work { |
| 109 | fmt.Printf("WORK=%s\n", tmpdir) |
| 110 | } |
| 111 | |
| 112 | // Look up the build cache directory, which is used to speed up incremental |
| 113 | // builds. |
| 114 | cacheDir := goenv.Get("GOCACHE") |
| 115 | if cacheDir == "off" { |
| 116 | // Use temporary build directory instead, effectively disabling the |
| 117 | // build cache. |
| 118 | cacheDir = tmpdir |
| 119 | } |
| 120 | |
| 121 | // Create default global values. |
| 122 | globalValues := map[string]map[string]string{ |
| 123 | "runtime": { |
| 124 | "buildVersion": goenv.Version(), |
| 125 | }, |
| 126 | "testing": {}, |
| 127 | } |
| 128 | if config.TestConfig.CompileTestBinary { |
| 129 | // The testing.testBinary is set to "1" when in a test. |
| 130 | // This is needed for testing.Testing() to work correctly. |
| 131 | globalValues["testing"]["testBinary"] = "1" |
| 132 | } |
| 133 | |
| 134 | // Copy over explicitly set global values, like |
| 135 | // -ldflags="-X main.Version="1.0" |
| 136 | for pkgPath, vals := range config.Options.GlobalValues { |
| 137 | if _, ok := globalValues[pkgPath]; !ok { |
| 138 | globalValues[pkgPath] = map[string]string{} |
| 139 | } |
| 140 | for k, v := range vals { |
| 141 | globalValues[pkgPath][k] = v |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | // Check for a libc dependency. |
| 146 | // As a side effect, this also creates the headers for the given libc, if |
| 147 | // the libc needs them. |
| 148 | root := goenv.Get("TINYGOROOT") |
| 149 | var libcDependencies []*compileJob |
| 150 | switch config.Target.Libc { |
| 151 | case "darwin-libSystem": |
| 152 | libcJob := makeDarwinLibSystemJob(config, tmpdir) |
| 153 | libcDependencies = append(libcDependencies, libcJob) |
| 154 | case "musl": |
| 155 | var unlock func() |
| 156 | libcJob, unlock, err := libMusl.load(config, tmpdir) |
| 157 | if err != nil { |