github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/builder/mingw-w64.go (about)

     1  package builder
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/tinygo-org/tinygo/goenv"
    11  )
    12  
    13  var MinGW = Library{
    14  	name: "mingw-w64",
    15  	makeHeaders: func(target, includeDir string) error {
    16  		// copy _mingw.h
    17  		srcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib", "mingw-w64")
    18  		outf, err := os.Create(includeDir + "/_mingw.h")
    19  		if err != nil {
    20  			return err
    21  		}
    22  		defer outf.Close()
    23  		inf, err := os.Open(srcDir + "/mingw-w64-headers/crt/_mingw.h.in")
    24  		if err != nil {
    25  			return err
    26  		}
    27  		_, err = io.Copy(outf, inf)
    28  		return err
    29  	},
    30  	sourceDir: func() string { return "" }, // unused
    31  	cflags: func(target, headerPath string) []string {
    32  		// No flags necessary because there are no files to compile.
    33  		return nil
    34  	},
    35  	librarySources: func(target string) ([]string, error) {
    36  		// We only use the UCRT DLL file. No source files necessary.
    37  		return nil, nil
    38  	},
    39  }
    40  
    41  // makeMinGWExtraLibs returns a slice of jobs to import the correct .dll
    42  // libraries. This is done by converting input .def files to .lib files which
    43  // can then be linked as usual.
    44  //
    45  // TODO: cache the result. At the moment, it costs a few hundred milliseconds to
    46  // compile these files.
    47  func makeMinGWExtraLibs(tmpdir, goarch string) []*compileJob {
    48  	var jobs []*compileJob
    49  	root := goenv.Get("TINYGOROOT")
    50  	// Normally all the api-ms-win-crt-*.def files are all compiled to a single
    51  	// .lib file. But to simplify things, we're going to leave them as separate
    52  	// files.
    53  	for _, name := range []string{
    54  		"kernel32.def.in",
    55  		"api-ms-win-crt-conio-l1-1-0.def",
    56  		"api-ms-win-crt-convert-l1-1-0.def.in",
    57  		"api-ms-win-crt-environment-l1-1-0.def",
    58  		"api-ms-win-crt-filesystem-l1-1-0.def",
    59  		"api-ms-win-crt-heap-l1-1-0.def",
    60  		"api-ms-win-crt-locale-l1-1-0.def",
    61  		"api-ms-win-crt-math-l1-1-0.def.in",
    62  		"api-ms-win-crt-multibyte-l1-1-0.def",
    63  		"api-ms-win-crt-private-l1-1-0.def.in",
    64  		"api-ms-win-crt-process-l1-1-0.def",
    65  		"api-ms-win-crt-runtime-l1-1-0.def.in",
    66  		"api-ms-win-crt-stdio-l1-1-0.def",
    67  		"api-ms-win-crt-string-l1-1-0.def",
    68  		"api-ms-win-crt-time-l1-1-0.def",
    69  		"api-ms-win-crt-utility-l1-1-0.def",
    70  	} {
    71  		outpath := filepath.Join(tmpdir, filepath.Base(name)+".lib")
    72  		inpath := filepath.Join(root, "lib/mingw-w64/mingw-w64-crt/lib-common/"+name)
    73  		job := &compileJob{
    74  			description: "create lib file " + inpath,
    75  			result:      outpath,
    76  			run: func(job *compileJob) error {
    77  				defpath := inpath
    78  				var archDef, emulation string
    79  				switch goarch {
    80  				case "amd64":
    81  					archDef = "-DDEF_X64"
    82  					emulation = "i386pep"
    83  				case "arm64":
    84  					archDef = "-DDEF_ARM64"
    85  					emulation = "arm64pe"
    86  				default:
    87  					return fmt.Errorf("unsupported architecture for mingw-w64: %s", goarch)
    88  				}
    89  				if strings.HasSuffix(inpath, ".in") {
    90  					// .in files need to be preprocessed by a preprocessor (-E)
    91  					// first.
    92  					defpath = outpath + ".def"
    93  					err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", archDef, "-DDATA", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/")
    94  					if err != nil {
    95  						return err
    96  					}
    97  				}
    98  				return link("ld.lld", "-m", emulation, "-o", outpath, defpath)
    99  			},
   100  		}
   101  		jobs = append(jobs, job)
   102  	}
   103  	return jobs
   104  }