MCPcopy
hub / github.com/tinygo-org/tinygo / buildAndRun

Function buildAndRun

main.go:847–1017  ·  view source on GitHub ↗

buildAndRun builds and runs the given program, writing output to stdout and errors to os.Stderr. It takes care of emulators (qemu, wasmtime, etc) and passes command line arguments and environment variables in a way appropriate for the given emulator.

(pkgName string, config *compileopts.Config, stdout io.Writer, cmdArgs, environmentVars []string, timeout time.Duration, run func(cmd *exec.Cmd, result builder.BuildResult) error)

Source from the content-addressed store, hash-verified

845// passes command line arguments and environment variables in a way appropriate
846// for the given emulator.
847func buildAndRun(pkgName string, config *compileopts.Config, stdout io.Writer, cmdArgs, environmentVars []string, timeout time.Duration, run func(cmd *exec.Cmd, result builder.BuildResult) error) (builder.BuildResult, error) {
848 // Determine whether we're on a system that supports environment variables
849 // and command line parameters (operating systems, WASI) or not (baremetal,
850 // WebAssembly in the browser). If we're on a system without an environment,
851 // we need to pass command line arguments and environment variables through
852 // global variables (built into the binary directly) instead of the
853 // conventional way.
854 needsEnvInVars := config.GOOS() == "js"
855 for _, tag := range config.BuildTags() {
856 if tag == "baremetal" {
857 needsEnvInVars = true
858 }
859 }
860 var args, env []string
861 var extraCmdEnv []string
862 if needsEnvInVars {
863 runtimeGlobals := make(map[string]string)
864 if len(cmdArgs) != 0 {
865 runtimeGlobals["osArgs"] = strings.Join(cmdArgs, "\x00")
866 }
867 if len(environmentVars) != 0 {
868 runtimeGlobals["osEnv"] = strings.Join(environmentVars, "\x00")
869 }
870 if len(runtimeGlobals) != 0 {
871 // This sets the global variables like they would be set with
872 // `-ldflags="-X=runtime.osArgs=first\x00second`.
873 // The runtime package has two variables (osArgs and osEnv) that are
874 // both strings, from which the parameters and environment variables
875 // are read.
876 config.Options.GlobalValues = map[string]map[string]string{
877 "runtime": runtimeGlobals,
878 }
879 }
880 } else {
881 // Pass environment variables and command line parameters as usual.
882 // This also works on qemu-aarch64 etc.
883 args = cmdArgs
884 env = environmentVars
885 }
886
887 // Create a temporary directory for intermediary files.
888 tmpdir, err := os.MkdirTemp("", "tinygo")
889 if err != nil {
890 return builder.BuildResult{}, err
891 }
892 if !config.Options.Work {
893 defer os.RemoveAll(tmpdir)
894 }
895
896 // Build the binary to be run.
897 format, fileExt := config.EmulatorFormat()
898 result, err := builder.Build(pkgName, fileExt, tmpdir, config)
899 if err != nil {
900 return result, err
901 }
902
903 // If needed, set a timeout on the command. This is done in tests so
904 // they don't waste resources on a stalled test.

Callers 4

runTestWithConfigFunction · 0.85
TestWasmExitFunction · 0.85
TestFunction · 0.85
RunFunction · 0.85

Calls 11

BuildFunction · 0.92
dirsToModuleRootRelFunction · 0.85
dirsToModuleRootAbsFunction · 0.85
newOutputWriterFunction · 0.85
GOOSMethod · 0.80
BuildTagsMethod · 0.80
EmulatorFormatMethod · 0.80
EmulatorMethod · 0.80
EmulatorNameMethod · 0.80
ErrMethod · 0.80
runFunction · 0.50

Tested by 3

runTestWithConfigFunction · 0.68
TestWasmExitFunction · 0.68
TestFunction · 0.68