mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-15 00:13:43 +00:00
WIP try to use MSVCRT.DLL instead of UCRT
Very simple "hello world" style programs work.
This commit is contained in:
@@ -3,6 +3,7 @@ package builder
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/tinygo-org/tinygo/compileopts"
|
"github.com/tinygo-org/tinygo/compileopts"
|
||||||
"github.com/tinygo-org/tinygo/goenv"
|
"github.com/tinygo-org/tinygo/goenv"
|
||||||
@@ -229,6 +230,10 @@ var libCompilerRT = Library{
|
|||||||
builtins = append(builtins, avrBuiltins...)
|
builtins = append(builtins, avrBuiltins...)
|
||||||
case "x86_64", "aarch64", "riscv64": // any 64-bit arch
|
case "x86_64", "aarch64", "riscv64": // any 64-bit arch
|
||||||
builtins = append(builtins, genericBuiltins128...)
|
builtins = append(builtins, genericBuiltins128...)
|
||||||
|
case "i386":
|
||||||
|
if strings.Split(target, "-")[2] == "windows" {
|
||||||
|
builtins = append(builtins, "i386/chkstk.S")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return builtins, nil
|
return builtins, nil
|
||||||
},
|
},
|
||||||
|
|||||||
+75
-31
@@ -32,23 +32,54 @@ var libMinGW = Library{
|
|||||||
mingwDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/mingw-w64")
|
mingwDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/mingw-w64")
|
||||||
return []string{
|
return []string{
|
||||||
"-nostdlibinc",
|
"-nostdlibinc",
|
||||||
|
"-isystem", mingwDir + "/mingw-w64-crt/include",
|
||||||
"-isystem", mingwDir + "/mingw-w64-headers/crt",
|
"-isystem", mingwDir + "/mingw-w64-headers/crt",
|
||||||
|
"-isystem", mingwDir + "/mingw-w64-headers/include",
|
||||||
"-I", mingwDir + "/mingw-w64-headers/defaults/include",
|
"-I", mingwDir + "/mingw-w64-headers/defaults/include",
|
||||||
"-I" + headerPath,
|
"-I" + headerPath,
|
||||||
|
"-D__MSVCRT_VERSION__=0x700", // Microsoft Visual C++ .NET 2002
|
||||||
|
"-D_WIN32_WINNT=0x0501", // target Windows XP
|
||||||
|
"-D__LIBMSVCRT_OS__",
|
||||||
|
"-D_CRTBLD",
|
||||||
|
"-Wno-pragma-pack",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
librarySources: func(target string) ([]string, error) {
|
librarySources: func(target string) ([]string, error) {
|
||||||
// These files are needed so that printf and the like are supported.
|
// These files are needed so that printf and the like are supported.
|
||||||
sources := []string{
|
var sources []string
|
||||||
"mingw-w64-crt/stdio/ucrt_fprintf.c",
|
if strings.Split(target, "-")[0] == "i386" {
|
||||||
"mingw-w64-crt/stdio/ucrt_fwprintf.c",
|
// Old 32-bit x86 systems use msvcrt.dll.
|
||||||
"mingw-w64-crt/stdio/ucrt_printf.c",
|
sources = []string{
|
||||||
"mingw-w64-crt/stdio/ucrt_snprintf.c",
|
"mingw-w64-crt/crt/pseudo-reloc.c",
|
||||||
"mingw-w64-crt/stdio/ucrt_sprintf.c",
|
"mingw-w64-crt/gdtoa/dmisc.c",
|
||||||
"mingw-w64-crt/stdio/ucrt_vfprintf.c",
|
"mingw-w64-crt/gdtoa/gdtoa.c",
|
||||||
"mingw-w64-crt/stdio/ucrt_vprintf.c",
|
"mingw-w64-crt/gdtoa/gmisc.c",
|
||||||
"mingw-w64-crt/stdio/ucrt_vsnprintf.c",
|
"mingw-w64-crt/gdtoa/misc.c",
|
||||||
"mingw-w64-crt/stdio/ucrt_vsprintf.c",
|
"mingw-w64-crt/misc/___mb_cur_max_func.c",
|
||||||
|
"mingw-w64-crt/misc/lc_locale_func.c",
|
||||||
|
"mingw-w64-crt/misc/mbrtowc.c",
|
||||||
|
"mingw-w64-crt/misc/strnlen.c",
|
||||||
|
"mingw-w64-crt/misc/wcrtomb.c",
|
||||||
|
"mingw-w64-crt/secapi/rand_s.c",
|
||||||
|
"mingw-w64-crt/stdio/acrt_iob_func.c",
|
||||||
|
"mingw-w64-crt/stdio/mingw_lock.c",
|
||||||
|
"mingw-w64-crt/stdio/mingw_pformat.c",
|
||||||
|
"mingw-w64-crt/stdio/mingw_vfprintf.c",
|
||||||
|
"mingw-w64-crt/stdio/mingw_vsnprintf.c",
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Anything somewhat modern (amd64, arm64) uses UCRT.
|
||||||
|
sources = []string{
|
||||||
|
"mingw-w64-crt/stdio/ucrt_fprintf.c",
|
||||||
|
"mingw-w64-crt/stdio/ucrt_fwprintf.c",
|
||||||
|
"mingw-w64-crt/stdio/ucrt_printf.c",
|
||||||
|
"mingw-w64-crt/stdio/ucrt_snprintf.c",
|
||||||
|
"mingw-w64-crt/stdio/ucrt_sprintf.c",
|
||||||
|
"mingw-w64-crt/stdio/ucrt_vfprintf.c",
|
||||||
|
"mingw-w64-crt/stdio/ucrt_vprintf.c",
|
||||||
|
"mingw-w64-crt/stdio/ucrt_vsnprintf.c",
|
||||||
|
"mingw-w64-crt/stdio/ucrt_vsprintf.c",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sources, nil
|
return sources, nil
|
||||||
},
|
},
|
||||||
@@ -63,27 +94,40 @@ var libMinGW = Library{
|
|||||||
func makeMinGWExtraLibs(tmpdir, goarch string) []*compileJob {
|
func makeMinGWExtraLibs(tmpdir, goarch string) []*compileJob {
|
||||||
var jobs []*compileJob
|
var jobs []*compileJob
|
||||||
root := goenv.Get("TINYGOROOT")
|
root := goenv.Get("TINYGOROOT")
|
||||||
// Normally all the api-ms-win-crt-*.def files are all compiled to a single
|
var libs []string
|
||||||
// .lib file. But to simplify things, we're going to leave them as separate
|
if goarch == "386" {
|
||||||
// files.
|
libs = []string{
|
||||||
for _, name := range []string{
|
// x86 uses msvcrt.dll instead of UCRT for compatibility with old
|
||||||
"kernel32.def.in",
|
// Windows versions.
|
||||||
"api-ms-win-crt-conio-l1-1-0.def",
|
"advapi32.def.in",
|
||||||
"api-ms-win-crt-convert-l1-1-0.def.in",
|
"kernel32.def.in",
|
||||||
"api-ms-win-crt-environment-l1-1-0.def",
|
"msvcrt.def.in",
|
||||||
"api-ms-win-crt-filesystem-l1-1-0.def",
|
}
|
||||||
"api-ms-win-crt-heap-l1-1-0.def",
|
} else {
|
||||||
"api-ms-win-crt-locale-l1-1-0.def",
|
// Use the modernized UCRT on new systems.
|
||||||
"api-ms-win-crt-math-l1-1-0.def.in",
|
// Normally all the api-ms-win-crt-*.def files are all compiled to a
|
||||||
"api-ms-win-crt-multibyte-l1-1-0.def",
|
// single .lib file. But to simplify things, we're going to leave them
|
||||||
"api-ms-win-crt-private-l1-1-0.def.in",
|
// as separate files.
|
||||||
"api-ms-win-crt-process-l1-1-0.def",
|
libs = []string{
|
||||||
"api-ms-win-crt-runtime-l1-1-0.def.in",
|
"kernel32.def.in",
|
||||||
"api-ms-win-crt-stdio-l1-1-0.def",
|
"api-ms-win-crt-conio-l1-1-0.def",
|
||||||
"api-ms-win-crt-string-l1-1-0.def",
|
"api-ms-win-crt-convert-l1-1-0.def.in",
|
||||||
"api-ms-win-crt-time-l1-1-0.def",
|
"api-ms-win-crt-environment-l1-1-0.def",
|
||||||
"api-ms-win-crt-utility-l1-1-0.def",
|
"api-ms-win-crt-filesystem-l1-1-0.def",
|
||||||
} {
|
"api-ms-win-crt-heap-l1-1-0.def",
|
||||||
|
"api-ms-win-crt-locale-l1-1-0.def",
|
||||||
|
"api-ms-win-crt-math-l1-1-0.def.in",
|
||||||
|
"api-ms-win-crt-multibyte-l1-1-0.def",
|
||||||
|
"api-ms-win-crt-private-l1-1-0.def.in",
|
||||||
|
"api-ms-win-crt-process-l1-1-0.def",
|
||||||
|
"api-ms-win-crt-runtime-l1-1-0.def.in",
|
||||||
|
"api-ms-win-crt-stdio-l1-1-0.def",
|
||||||
|
"api-ms-win-crt-string-l1-1-0.def",
|
||||||
|
"api-ms-win-crt-time-l1-1-0.def",
|
||||||
|
"api-ms-win-crt-utility-l1-1-0.def",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, name := range libs {
|
||||||
outpath := filepath.Join(tmpdir, filepath.Base(name)+".lib")
|
outpath := filepath.Join(tmpdir, filepath.Base(name)+".lib")
|
||||||
inpath := filepath.Join(root, "lib/mingw-w64/mingw-w64-crt/lib-common/"+name)
|
inpath := filepath.Join(root, "lib/mingw-w64/mingw-w64-crt/lib-common/"+name)
|
||||||
job := &compileJob{
|
job := &compileJob{
|
||||||
|
|||||||
+13
-3
@@ -391,15 +391,25 @@ func (c *Config) LibcCFlags() []string {
|
|||||||
case "mingw-w64":
|
case "mingw-w64":
|
||||||
root := goenv.Get("TINYGOROOT")
|
root := goenv.Get("TINYGOROOT")
|
||||||
path, _ := c.LibcPath("mingw-w64")
|
path, _ := c.LibcPath("mingw-w64")
|
||||||
return []string{
|
cflags := []string{
|
||||||
"-nostdlibinc",
|
"-nostdlibinc",
|
||||||
"-isystem", filepath.Join(path, "include"),
|
"-isystem", filepath.Join(path, "include"),
|
||||||
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"),
|
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"),
|
||||||
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "include"),
|
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "include"),
|
||||||
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"),
|
"-isystem", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"),
|
||||||
"-D_UCRT",
|
|
||||||
"-D_WIN32_WINNT=0x0a00", // target Windows 10
|
|
||||||
}
|
}
|
||||||
|
if c.GOARCH() == "386" {
|
||||||
|
cflags = append(cflags,
|
||||||
|
"-D__MSVCRT_VERSION__=0x700", // Microsoft Visual C++ .NET 2002
|
||||||
|
"-D_WIN32_WINNT=0x0501", // target Windows XP
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
cflags = append(cflags,
|
||||||
|
"-D_UCRT",
|
||||||
|
"-D_WIN32_WINNT=0x0a00", // target Windows 10
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return cflags
|
||||||
case "":
|
case "":
|
||||||
// No libc specified, nothing to add.
|
// No libc specified, nothing to add.
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ func (r *reader) Read(b []byte) (n int, err error) {
|
|||||||
// Call rand_s every four bytes because it's a C int (always 32-bit in
|
// Call rand_s every four bytes because it's a C int (always 32-bit in
|
||||||
// Windows).
|
// Windows).
|
||||||
if i%4 == 0 {
|
if i%4 == 0 {
|
||||||
|
// TODO: use RtlGenRandom on GOARCH=386.
|
||||||
errCode := libc_rand_s(&randomByte)
|
errCode := libc_rand_s(&randomByte)
|
||||||
if errCode != 0 {
|
if errCode != 0 {
|
||||||
// According to the documentation, it can return an error.
|
// According to the documentation, it can return an error.
|
||||||
|
|||||||
@@ -239,11 +239,17 @@ func procUnpin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func hardwareRand() (n uint64, ok bool) {
|
func hardwareRand() (n uint64, ok bool) {
|
||||||
var n1, n2 uint32
|
if GOARCH == "386" {
|
||||||
errCode1 := libc_rand_s(&n1)
|
// Use the old RtlGenRandom, introduced in Windows XP.
|
||||||
errCode2 := libc_rand_s(&n2)
|
ok = RtlGenRandom(unsafe.Pointer(&n), 8)
|
||||||
n = uint64(n1)<<32 | uint64(n2)
|
} else {
|
||||||
ok = errCode1 == 0 && errCode2 == 0
|
// Use the newer secure rand_s function that's part of UCRT.
|
||||||
|
var n1, n2 uint32
|
||||||
|
errCode1 := libc_rand_s(&n1)
|
||||||
|
errCode2 := libc_rand_s(&n2)
|
||||||
|
n = uint64(n1)<<32 | uint64(n2)
|
||||||
|
ok = errCode1 == 0 && errCode2 == 0
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,3 +259,10 @@ func hardwareRand() (n uint64, ok bool) {
|
|||||||
//
|
//
|
||||||
//export rand_s
|
//export rand_s
|
||||||
func libc_rand_s(randomValue *uint32) int32
|
func libc_rand_s(randomValue *uint32) int32
|
||||||
|
|
||||||
|
// This function is part of advapi32.dll, and is called SystemFunction036 for
|
||||||
|
// some reason. It's available on Windows XP and newer.
|
||||||
|
// See: https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
|
||||||
|
//
|
||||||
|
//export SystemFunction036
|
||||||
|
func RtlGenRandom(buf unsafe.Pointer, len int) bool
|
||||||
|
|||||||
Reference in New Issue
Block a user