golang.org/x/build@v0.0.0-20240506185731-218518f32b70/cmd/runqemubuildlet/darwin.go (about)

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"fmt"
     9  	"log"
    10  	"os"
    11  	"os/exec"
    12  	"path/filepath"
    13  )
    14  
    15  // defaultDarwinDir returns a default path for a darwin VM.
    16  //
    17  // The directory should contain the darwin VM image, and QEMU
    18  // (sysroot-macos-x86_64).
    19  func defaultDarwinDir() string {
    20  	home, err := os.UserHomeDir()
    21  	if err != nil {
    22  		log.Printf("os.UserHomeDir() = %q, %v", home, err)
    23  		return ""
    24  	}
    25  	return home
    26  }
    27  
    28  // darwinCmd returns a qemu command for running a darwin VM, ready
    29  // to be started.
    30  func darwinCmd(base string) *exec.Cmd {
    31  	if *macosVersion == 0 {
    32  		log.Fatalf("-macos-version required")
    33  	}
    34  	if *osk == "" {
    35  		log.Fatalf("-osk required")
    36  	}
    37  
    38  	sysroot := filepath.Join(base, "sysroot-macos-x86_64")
    39  	ovmfCode := filepath.Join(sysroot, "share/qemu/edk2-x86_64-code.fd")
    40  
    41  	disk := filepath.Join(base, "macos.qcow2")
    42  
    43  	// Note that vmnet-shared requires that we run QEMU as root, so
    44  	// runqemubuildlet must run as root.
    45  	//
    46  	// These arguments should be kept in sync with env/darwin/aws/qemu.sh.
    47  	args := []string{
    48  		// Discard disk changes on exit.
    49  		"-snapshot",
    50  		"-m", "10240",
    51  		"-cpu", "host",
    52  		"-machine", "q35",
    53  		"-usb",
    54  		"-device", "usb-kbd",
    55  		"-device", "usb-tablet",
    56  		// macOS only likes a power-of-two number of cores, but odd socket count is
    57  		// fine.
    58  		"-smp", "cpus=6,sockets=3,cores=2,threads=1",
    59  		"-device", "usb-ehci,id=ehci",
    60  		"-device", "nec-usb-xhci,id=xhci",
    61  		"-global", "nec-usb-xhci.msi=off",
    62  		"-device", fmt.Sprintf("isa-applesmc,osk=%s", *osk),
    63  		"-drive", fmt.Sprintf("if=pflash,format=raw,readonly=on,file=%s", ovmfCode),
    64  		"-smbios", "type=2",
    65  		"-device", "ich9-intel-hda",
    66  		"-device", "hda-duplex",
    67  		"-device", "ich9-ahci,id=sata",
    68  		"-drive", fmt.Sprintf("id=MacHDD,if=none,format=qcow2,file=%s", disk),
    69  		"-device", "ide-hd,bus=sata.2,drive=MacHDD",
    70  		"-monitor", "stdio",
    71  		"-device", "VGA,vgamem_mb=128",
    72  		"-M", "accel=hvf",
    73  		"-display", fmt.Sprintf("vnc=127.0.0.1:%d", *guestIndex),
    74  		// DHCP range is a dummy range. The actual guest IP is assigned statically
    75  		// based on the MAC address matching an entry in /etc/bootptab.
    76  		"-netdev", "vmnet-shared,id=net0,start-address=192.168.64.1,end-address=192.168.64.100,subnet-mask=255.255.255.0",
    77  	}
    78  	if *macosVersion >= 11 {
    79  		args = append(args, "-device", fmt.Sprintf("virtio-net-pci,netdev=net0,id=net0,mac=52:54:00:c9:18:0%d", *guestIndex))
    80  	} else {
    81  		args = append(args, "-device", fmt.Sprintf("vmxnet3,netdev=net0,id=net0,mac=52:54:00:c9:18:0%d", *guestIndex))
    82  	}
    83  
    84  	cmd := exec.Command(filepath.Join(sysroot, "bin/qemu-system-x86_64"), args...)
    85  	cmd.Env = append(os.Environ(),
    86  		fmt.Sprintf("DYLD_LIBRARY_PATH=%s", filepath.Join(sysroot, "lib")),
    87  	)
    88  	return cmd
    89  }