@@ -80,17 +80,18 @@ type BuildResult struct {
8080// key, avoiding the need for recompiling all dependencies when only the
8181// implementation of an imported package changes.
8282type packageAction struct {
83- ImportPath string
84- CompilerBuildID string
85- TinyGoVersion string
86- LLVMVersion string
87- Config * compiler.Config
88- CFlags []string
89- FileHashes map [string ]string // hash of every file that's part of the package
90- EmbeddedFiles map [string ]string // hash of all the //go:embed files in the package
91- Imports map [string ]string // map from imported package to action ID hash
92- OptLevel string // LLVM optimization level (O0, O1, O2, Os, Oz)
93- UndefinedGlobals []string // globals that are left as external globals (no initializer)
83+ ImportPath string
84+ CompilerBuildID string
85+ TinyGoVersion string
86+ LLVMVersion string
87+ CCompilerIdentity string
88+ Config * compiler.Config
89+ CFlags []string
90+ FileHashes map [string ]string // hash of every file that's part of the package
91+ EmbeddedFiles map [string ]string // hash of all the //go:embed files in the package
92+ Imports map [string ]string // map from imported package to action ID hash
93+ OptLevel string // LLVM optimization level (O0, O1, O2, Os, Oz)
94+ UndefinedGlobals []string // globals that are left as external globals (no initializer)
9495}
9596
9697// Build performs a single package to executable Go build. It takes in a package
@@ -344,6 +345,13 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
344345 OptLevel : optLevel ,
345346 UndefinedGlobals : undefinedGlobals ,
346347 }
348+ if len (pkg .CGoHeaders ) != 0 {
349+ compilerID , err := clangCompilerIdentity ()
350+ if err != nil {
351+ return err
352+ }
353+ actionID .CCompilerIdentity = compilerID
354+ }
347355 for filePath , hash := range pkg .FileHashes {
348356 actionID .FileHashes [filePath ] = hex .EncodeToString (hash )
349357 }
@@ -398,9 +406,6 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
398406 }
399407
400408 // Load bitcode of CGo headers and join the modules together.
401- // This may seem vulnerable to cache problems, but this is not
402- // the case: the Go code that was just compiled already tracks
403- // all C files that are read and hashes them.
404409 // These headers could be compiled in parallel but the benefit
405410 // is so small that it's probably not worth parallelizing.
406411 // Packages are compiled independently anyway.
@@ -410,14 +415,16 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
410415 if err != nil {
411416 return err
412417 }
413- _ , err = f .Write ([]byte (cgoHeader ))
414- if err != nil {
418+ if _ , err := f .Write ([]byte (cgoHeader )); err != nil {
415419 return err
416420 }
417- f .Close ()
421+ if err := f .Close (); err != nil {
422+ return err
423+ }
424+ output := f .Name () + ".bc"
418425
419426 // Compile the code (if there is any) to bitcode.
420- flags := append ([] string { "-c" , "-emit-llvm" , "-o" , f .Name () + ".bc" , f . Name ()} , pkg .CFlags ... )
427+ flags := cgoHeaderCompileArgs ( f .Name (), output , pkg .CFlags )
421428 if config .Options .PrintCommands != nil {
422429 config .Options .PrintCommands ("clang" , flags ... )
423430 }
@@ -431,7 +438,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
431438 // in the header together with the Go code. In particular,
432439 // this allows inlining. It also ensures there is only one
433440 // file per package to cache.
434- headerMod , err := mod .Context ().ParseBitcodeFile (f . Name () + ".bc" )
441+ headerMod , err := mod .Context ().ParseBitcodeFile (output )
435442 if err != nil {
436443 return fmt .Errorf ("failed to load bitcode file: %w" , err )
437444 }
@@ -1074,6 +1081,15 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
10741081 return result , nil
10751082}
10761083
1084+ func cgoHeaderCompileArgs (source , output string , cflags []string ) []string {
1085+ flags := append ([]string {"-c" , "-emit-llvm" , "-o" , output , source }, cflags ... )
1086+ flags = append (flags ,
1087+ "-ffile-prefix-map=" + source + "=tinygo-cgo.c" ,
1088+ "-fdebug-prefix-map=" + source + "=tinygo-cgo.c" ,
1089+ )
1090+ return appendCacheStableCFlags (flags )
1091+ }
1092+
10771093// createEmbedObjectFile creates a new object file with the given contents, for
10781094// the embed package.
10791095func createEmbedObjectFile (data , hexSum , sourceFile , sourceDir , tmpdir string , compilerConfig * compiler.Config ) (string , error ) {
0 commit comments