Browse Source

main: escape commands while printing them with the -x flag

This should make issues such as the one in
https://github.com/tinygo-org/tinygo/issues/1910 more obvious.
pull/1932/head
Ayke van Laethem 3 years ago
committed by Ron Evans
parent
commit
4e610a0ee7
  1. 4
      builder/build.go
  2. 6
      builder/cc.go
  3. 2
      compileopts/options.go
  4. 27
      main.go

4
builder/build.go

@ -547,8 +547,8 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
}
ldflags = append(ldflags, dependency.result)
}
if config.Options.PrintCommands {
fmt.Printf("%s %s\n", config.Target.Linker, strings.Join(ldflags, " "))
if config.Options.PrintCommands != nil {
config.Options.PrintCommands(config.Target.Linker, ldflags...)
}
err = link(config.Target.Linker, ldflags...)
if err != nil {

6
builder/cc.go

@ -56,7 +56,7 @@ import (
// depfile but without invalidating its name. For this reason, the depfile is
// written on each new compilation (even when it seems unnecessary). However, it
// could in rare cases lead to a stale file fetched from the cache.
func compileAndCacheCFile(abspath, tmpdir string, cflags []string, printCommands bool) (string, error) {
func compileAndCacheCFile(abspath, tmpdir string, cflags []string, printCommands func(string, ...string)) (string, error) {
// Hash input file.
fileHash, err := hashFile(abspath)
if err != nil {
@ -128,8 +128,8 @@ func compileAndCacheCFile(abspath, tmpdir string, cflags []string, printCommands
// flags (for the assembler) is a compiler error.
flags = append(flags, "-Qunused-arguments")
}
if printCommands {
fmt.Printf("clang %s\n", strings.Join(flags, " "))
if printCommands != nil {
printCommands("clang", flags...)
}
err = runCCompiler(flags...)
if err != nil {

2
compileopts/options.go

@ -25,7 +25,7 @@ type Options struct {
PrintIR bool
DumpSSA bool
VerifyIR bool
PrintCommands bool
PrintCommands func(cmd string, args ...string)
Debug bool
PrintSizes string
PrintAllocs *regexp.Regexp // regexp string

27
main.go

@ -95,12 +95,31 @@ func copyFile(src, dst string) error {
// executeCommand is a simple wrapper to exec.Cmd
func executeCommand(options *compileopts.Options, name string, arg ...string) *exec.Cmd {
if options.PrintCommands {
fmt.Printf("%s %s\n", name, strings.Join(arg, " "))
if options.PrintCommands != nil {
options.PrintCommands(name, arg...)
}
return exec.Command(name, arg...)
}
// printCommand prints a command to stdout while formatting it like a real
// command (escaping characters etc). The resulting command should be easy to
// run directly in a shell, although it is not guaranteed to be a safe shell
// escape. That's not a problem as the primary use case is printing the command,
// not running it.
func printCommand(cmd string, args ...string) {
command := append([]string{cmd}, args...)
for i, arg := range command {
// Source: https://www.oreilly.com/library/view/learning-the-bash/1565923472/ch01s09.html
const specialChars = "~`#$&*()\\|[]{};'\"<>?! "
if strings.ContainsAny(arg, specialChars) {
// See: https://stackoverflow.com/questions/15783701/which-characters-need-to-be-escaped-when-using-bash
arg = "'" + strings.ReplaceAll(arg, `'`, `'\''`) + "'"
command[i] = arg
}
}
fmt.Fprintln(os.Stderr, strings.Join(command, " "))
}
// Build compiles and links the given package and writes it to outpath.
func Build(pkgName, outpath string, options *compileopts.Options) error {
config, err := builder.NewConfig(options)
@ -1008,7 +1027,6 @@ func main() {
PrintSizes: *printSize,
PrintStacks: *printStacks,
PrintAllocs: printAllocs,
PrintCommands: *printCommands,
Tags: *tags,
GlobalValues: globalVarValues,
WasmAbi: *wasmAbi,
@ -1016,6 +1034,9 @@ func main() {
OpenOCDCommands: ocdCommands,
LLVMFeatures: *llvmFeatures,
}
if *printCommands {
options.PrintCommands = printCommand
}
os.Setenv("CC", "clang -target="+*target)

Loading…
Cancel
Save