Golang中如何向cmd.exec传递-ldflags="-w"参数

Golang中如何向cmd.exec传递-ldflags="-w"参数 我正在尝试使用 -ldflags="-w" 标志调用命令行来构建Go应用程序,但尝试通过Go文件实现,如下所示:

//go:build tag_build
// +build tag_build

package main

import (
	"fmt"
	"os"
	"os/exec"
)

type platform struct {
	arch     string
	compiler string
}

type system struct {
	name string
	platform
}

func main() {
	var package_name = "goApp"
	var pwd = "D:/goEverywhere/go"
	var androidSDK = "C:/Users/hasan_yousef/AppData/Local/Android/Sdk"
	var ndk = androidSDK + "/ndk/25.1.8937393/toolchains/llvm/prebuilt/windows-x86_64/bin"

        os.Setenv("GOOS", "android")
	os.Setenv("CGO_ENABLED", "1")

	// 检查现有架构,例如:$ go tool dist list

	android := []system{
		system{
			name: "android-armv7a",
			platform: platform{
				arch:     "arm",
				compiler: "armv7a-linux-androideabi33-clang",
			},
		},
		system{
			name: "android-arm64",
			platform: platform{
				arch:     "arm64",
				compiler: "aarch64-linux-android33-clang",
			},
		},
		system{
			name: "android-x86",
			platform: platform{
				arch:     "386",
				compiler: "i686-linux-android33-clang",
			},
		},
		system{
			name: "android-x86_64",
			platform: platform{
				arch:     "amd64",
				compiler: "x86_64-linux-android33-clang",
			},
		},
	}

	for _, s := range android {
		switch s.name {
		case "android-armv7a":
			os.Setenv("GOARM", "7")
		default:
			os.Setenv("GOARM", "")
		}
		os.Setenv("GOARCH", s.platform.arch)
		os.Setenv("CC", ndk+"/"+s.platform.compiler)
		args := []string{"build", "-ldflags=\"-w\"",
			"-buildmode=c-shared", "-o",
			pwd + "/" + s.name + "/lib" + package_name +".so", package_name}

        // 或者
		//	cmd := exec.Command(fmt.Sprintf("go build -ldflags=\"-w\" -buildmode=c-shared -o %s/%s/lib%s.so %s", pwd, s.name, package_nmae, package_nmae))
		//cmd := exec.Command("go", "build", `-ldflags="-w"`, "-buildmode=c-shared", "-o", pwd+"/"+s.name+"/libfoo.so", package_nmae)

		cmd := exec.Command("go", args...)
		out, err := cmd.CombinedOutput()
		if err != nil {
			fmt.Printf("cmd.Run() failed with %v:\n\noutput:\n\n%s\n", err, out)
		}
	}
}

编译时出现以下错误:

PS D:\goEverywhere\go> go run android_build.go
cmd.Run() failed with exit status 2:

output:

invalid value "\"-w\"" for flag -ldflags: missing =<value> in <pattern>=<value>
usage: go build [-o output] [build flags] [packages]
Run 'go help build' for details.

更多关于Golang中如何向cmd.exec传递-ldflags="-w"参数的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我发现 引号是给 shell 使用的,不能成为参数的一部分。 我移除了它们,现在代码可以正常工作了,如下所示:

//go:build tag_build
// +build tag_build

package main

import (
	"fmt"
	"os"
	"os/exec"
)

type platform struct {
	arch     string
	compiler string
}

type system struct {
	name string
	platform
}

func main() {
	var package_name = "goApp"
	var pwd = "D:/goEverywhere/go"
	var androidSDK = "C:/Users/hasan_yousef/AppData/Local/Android/Sdk"
	var ndk = androidSDK + "/ndk/25.1.8937393/toolchains/llvm/prebuilt/windows-x86_64/bin"
	os.Setenv("GOOS", "android")
	os.Setenv("CGO_ENABLED", "1")
	// go tool dist list
	android := []system{
		system{
			name: "android-armv7a",
			platform: platform{
				arch:     "arm",
				compiler: "armv7a-linux-androideabi33-clang",
			},
		},
		system{
			name: "android-arm64",
			platform: platform{
				arch:     "arm64",
				compiler: "aarch64-linux-android33-clang",
			},
		},
		system{
			name: "android-x86",
			platform: platform{
				arch:     "386",
				compiler: "i686-linux-android33-clang",
			},
		},
		system{
			name: "android-x86_64",
			platform: platform{
				arch:     "amd64",
				compiler: "x86_64-linux-android33-clang",
			},
		},
	}

	for _, s := range android {
		switch s.name {
		case "android-armv7a":
			os.Setenv("GOARM", "7")
		default:
			os.Setenv("GOARM", "")
		}
		os.Setenv("GOARCH", s.platform.arch)
		os.Setenv("CC", ndk+"/"+s.platform.compiler)
		//	args := []string{"build", "-ldflags=-w",
		//		"-buildmode=c-shared", "-o",
		//		pwd + "/" + s.name + "/lib" + package_name + ".so", package_name}

		cmd := exec.Command("go", "build", "-ldflags=-w", "-buildmode=c-shared", "-o", pwd+"/"+s.name+"/lib"+package_name+".so", package_name)
		//	cmd := exec.Command("go", args...)
		out, err := cmd.CombinedOutput()
		if err != nil {
			fmt.Printf("cmd.Run() failed with %v:\n\noutput:\n\n%s\n", err, out)
		}
	}
}

更多关于Golang中如何向cmd.exec传递-ldflags="-w"参数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


exec.Command 中传递 -ldflags="-w" 参数时,需要将 -ldflags"-w" 作为两个独立的参数传递。以下是修正后的代码示例:

args := []string{"build", "-ldflags", "-w",
    "-buildmode=c-shared", "-o",
    pwd + "/" + s.name + "/lib" + package_name + ".so", package_name}

或者使用 = 连接的形式:

args := []string{"build", "-ldflags=-w",
    "-buildmode=c-shared", "-o",
    pwd + "/" + s.name + "/lib" + package_name + ".so", package_name}

完整的修正示例:

func main() {
    var package_name = "goApp"
    var pwd = "D:/goEverywhere/go"
    var androidSDK = "C:/Users/hasan_yousef/AppData/Local/Android/Sdk"
    var ndk = androidSDK + "/ndk/25.1.8937393/toolchains/llvm/prebuilt/windows-x86_64/bin"

    os.Setenv("GOOS", "android")
    os.Setenv("CGO_ENABLED", "1")

    android := []system{
        {
            name: "android-armv7a",
            platform: platform{
                arch:     "arm",
                compiler: "armv7a-linux-androideabi33-clang",
            },
        },
        {
            name: "android-arm64",
            platform: platform{
                arch:     "arm64",
                compiler: "aarch64-linux-android33-clang",
            },
        },
        {
            name: "android-x86",
            platform: platform{
                arch:     "386",
                compiler: "i686-linux-android33-clang",
            },
        },
        {
            name: "android-x86_64",
            platform: platform{
                arch:     "amd64",
                compiler: "x86_64-linux-android33-clang",
            },
        },
    }

    for _, s := range android {
        switch s.name {
        case "android-armv7a":
            os.Setenv("GOARM", "7")
        default:
            os.Setenv("GOARM", "")
        }
        os.Setenv("GOARCH", s.platform.arch)
        os.Setenv("CC", ndk+"/"+s.platform.compiler)
        
        // 修正ldflags参数传递方式
        args := []string{"build", "-ldflags", "-w",
            "-buildmode=c-shared", "-o",
            pwd + "/" + s.name + "/lib" + package_name + ".so", package_name}

        cmd := exec.Command("go", args...)
        out, err := cmd.CombinedOutput()
        if err != nil {
            fmt.Printf("cmd.Run() failed with %v:\n\noutput:\n\n%s\n", err, out)
        }
    }
}

如果还需要传递其他链接器标志,可以这样组合:

args := []string{"build", "-ldflags", "-w -s",
    "-buildmode=c-shared", "-o",
    pwd + "/" + s.name + "/lib" + package_name + ".so", package_name}

或者使用多行格式提高可读性:

args := []string{
    "build",
    "-ldflags", "-w -s",
    "-buildmode", "c-shared",
    "-o", pwd + "/" + s.name + "/lib" + package_name + ".so",
    package_name,
}
回到顶部