zoukankan      html  css  js  c++  java
  • golang编译

     小结:

    go build -ldflags "-H windowsgui -X main.TaskType=PING -X main.BuildVersion=v1"  -o  App.exe;

    例:编译的时候,带上编译的人的姓名

    go build -ldflags "-X main.Developer=zhangsan"
    1
    main.go

    package main

    import "fmt"

    var Developer string

    func main() {
    fmt.Println("Developer:", Developer)
    }

    C:>go help build
    usage: go build [-o output] [build flags] [packages]

    Build compiles the packages named by the import paths,
    along with their dependencies, but it does not install the results.

    If the arguments to build are a list of .go files from a single directory,
    build treats them as a list of source files specifying a single package.

    When compiling packages, build ignores files that end in '_test.go'.

    When compiling a single main package, build writes
    the resulting executable to an output file named after
    the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe')
    or the source code directory ('go build unix/sam' writes 'sam' or 'sam.exe').
    The '.exe' suffix is added when writing a Windows executable.

    When compiling multiple packages or a single non-main package,
    build compiles the packages but discards the resulting object,
    serving only as a check that the packages can be built.

    The -o flag forces build to write the resulting executable or object
    to the named output file or directory, instead of the default behavior described
    in the last two paragraphs. If the named output is an existing directory or
    ends with a slash or backslash, then any resulting executables
    will be written to that directory.

    The -i flag installs the packages that are dependencies of the target.
    The -i flag is deprecated. Compiled packages are cached automatically.

    The build flags are shared by the build, clean, get, install, list, run,
    and test commands:

    -a
    force rebuilding of packages that are already up-to-date.
    -n
    print the commands but do not run them.
    -p n
    the number of programs, such as build commands or
    test binaries, that can be run in parallel.
    The default is the number of CPUs available.
    -race
    enable data race detection.
    Supported only on linux/amd64, freebsd/amd64, darwin/amd64, windows/amd64,
    linux/ppc64le and linux/arm64 (only for 48-bit VMA).
    -msan
    enable interoperation with memory sanitizer.
    Supported only on linux/amd64, linux/arm64
    and only with Clang/LLVM as the host C compiler.
    On linux/arm64, pie build mode will be used.
    -v
    print the names of packages as they are compiled.
    -work
    print the name of the temporary work directory and
    do not delete it when exiting.
    -x
    print the commands.

    -asmflags '[pattern=]arg list'
    arguments to pass on each go tool asm invocation.
    -buildmode mode
    build mode to use. See 'go help buildmode' for more.
    -compiler name
    name of compiler to use, as in runtime.Compiler (gccgo or gc).
    -gccgoflags '[pattern=]arg list'
    arguments to pass on each gccgo compiler/linker invocation.
    -gcflags '[pattern=]arg list'
    arguments to pass on each go tool compile invocation.
    -installsuffix suffix
    a suffix to use in the name of the package installation directory,
    in order to keep output separate from default builds.
    If using the -race flag, the install suffix is automatically set to race
    or, if set explicitly, has _race appended to it. Likewise for the -msan
    flag. Using a -buildmode option that requires non-default compile flags
    has a similar effect.
    -ldflags '[pattern=]arg list'
    arguments to pass on each go tool link invocation.
    -linkshared
    build code that will be linked against shared libraries previously
    created with -buildmode=shared.
    -mod mode
    module download mode to use: readonly, vendor, or mod.
    By default, if a vendor directory is present and the go version in go.mod
    is 1.14 or higher, the go command acts as if -mod=vendor were set.
    Otherwise, the go command acts as if -mod=readonly were set.
    See https://golang.org/ref/mod#build-commands for details.
    -modcacherw
    leave newly-created directories in the module cache read-write
    instead of making them read-only.
    -modfile file
    in module aware mode, read (and possibly write) an alternate go.mod
    file instead of the one in the module root directory. A file named
    "go.mod" must still be present in order to determine the module root
    directory, but it is not accessed. When -modfile is specified, an
    alternate go.sum file is also used: its path is derived from the
    -modfile flag by trimming the ".mod" extension and appending ".sum".
    -overlay file
    read a JSON config file that provides an overlay for build operations.
    The file is a JSON struct with a single field, named 'Replace', that
    maps each disk file path (a string) to its backing file path, so that
    a build will run as if the disk file path exists with the contents
    given by the backing file paths, or as if the disk file path does not
    exist if its backing file path is empty. Support for the -overlay flag
    has some limitations:importantly, cgo files included from outside the
    include path must be in the same directory as the Go package they are
    included from, and overlays will not appear when binaries and tests are
    run through go run and go test respectively.
    -pkgdir dir
    install and load all packages from dir instead of the usual locations.
    For example, when building with a non-standard configuration,
    use -pkgdir to keep generated packages in a separate location.
    -tags tag,list
    a comma-separated list of build tags to consider satisfied during the
    build. For more information about build tags, see the description of
    build constraints in the documentation for the go/build package.
    (Earlier versions of Go used a space-separated list, and that form
    is deprecated but still recognized.)
    -trimpath
    remove all file system paths from the resulting executable.
    Instead of absolute file system paths, the recorded file names
    will begin with either "go" (for the standard library),
    or a module path@version (when using modules),
    or a plain import path (when using GOPATH).
    -toolexec 'cmd args'
    a program to use to invoke toolchain programs like vet and asm.
    For example, instead of running asm, the go command will run
    'cmd args /path/to/asm <arguments for asm>'.

    The -asmflags, -gccgoflags, -gcflags, and -ldflags flags accept a
    space-separated list of arguments to pass to an underlying tool
    during the build. To embed spaces in an element in the list, surround
    it with either single or double quotes. The argument list may be
    preceded by a package pattern and an equal sign, which restricts
    the use of that argument list to the building of packages matching
    that pattern (see 'go help packages' for a description of package
    patterns). Without a pattern, the argument list applies only to the
    packages named on the command line. The flags may be repeated
    with different patterns in order to specify different arguments for
    different sets of packages. If a package matches patterns given in
    multiple flags, the latest match on the command line wins.
    For example, 'go build -gcflags=-S fmt' prints the disassembly
    only for package fmt, while 'go build -gcflags=all=-S fmt'
    prints the disassembly for fmt and all its dependencies.

    For more about specifying packages, see 'go help packages'.
    For more about where packages and binaries are installed,
    run 'go help gopath'.
    For more about calling between Go and C/C++, run 'go help c'.

    Note: Build adheres to certain conventions such as those described
    by 'go help gopath'. Not all projects can follow these conventions,
    however. Installations that have their own conventions or that use
    a separate software build system may choose to use lower-level
    invocations such as 'go tool compile' and 'go tool link' to avoid
    some of the overheads and design decisions of the build tool.

    See also: go install, go get, go clean.

    C:>go version
    go version go1.16.7 windows/amd64

    go build 可以用-gcflagsgo编译器传入参数,也就是传给go tool compile的参数,因此可以用go tool compile --help查看所有可用的参数。

    其中-m可以检查代码的编译优化情况,包括逃逸情况和函数是否内联。

    如果只在编译特定包时需要传递参数,格式应遵守“包名=参数列表”,如go build -gcflags -gcflags='log=-N -l' main.go

    go build用-ldflags给go链接器传入参数,实际是给go tool link的参数,可以用go tool link --help查看可用的参数。

    常用-X来指定版本号等编译时才决定的参数值。例如代码中定义var buildVer string,然后在编译时用go build -ldflags "-X main.buildVer=1.0" ... 来赋值。注意-X只能给string类型变量赋值。

    go build 参数汇总_DisMisPres的博客-CSDN博客 https://blog.csdn.net/DisMisPres/article/details/115110442

    go 的编译是以 package main 的 main() 函数作为主入口,生成可执行文件。若 build 的是非 main 包,则不会生成可执行文件,只检查是否可执行编译。
    可以输入 go help build 查看官方解释。
    go build 编译包时,会忽略“_test.go”结尾的文件(即测试文件)。

    参数 含义
    -o output 指定编译输出的名称,代替包名
    -i install 安装作为目标的依赖关系的包(用于增量编译提速)
    -a 强行对项目所有的代码包(包含标准库中的代码包)进行重新构建,即使它们已经是最新的了
    -n 打印编译期间所用到的命令,仅仅是打印并不真正执行它们
    -p n 指定编译过程中执行各任务的并行数量(确切地说应该是并发数量)。在默认情况下,该数量等于CPU的逻辑核数。但是在darwin/arm平台(即iPhone和iPad所用的平台)下,该数量默认是1
    -race 开启竞态条件的检测。不过此标记目前仅在linux/amd64、freebsd/amd64、darwin/amd64和windows/amd64平台下受到支持
    -msan 使用内存清除器启用互操作。只支持Linux/AMD 64、Linux/ARM 64,并且只有clang/llvm作为主机c+编译器
    -v 打印出那些被编译时的代码包的名字
    -x 打印编译期间所用到的其它命令(且执行),注意它与-n标记的区别
    -work 打印出编译时生成的临时工作目录的路径,并在编译结束时保留它。在默认情况下,编译结束时会删除该目录
    以下为不常用命令
    -asmflags 此标记可以后跟另外一些标记,如-D、-I、-S等。这些后跟的标记用于控制Go语言编译器编译汇编语言文件时的行为
    -buildmode 此标记用于指定编译模式,使用方式如-buildmode=default(这等同于默认情况下的设置)。此标记支持的编译模式目前有6种。借此,我们可以控制编译器在编译完成后生成静态链接库(即.a文件,也就是我们之前说的归档文件)、动态链接库(即.so文件)或/和可执行文件(在Windows下是.exe文件) go help buildmode
    -compiler 此标记用于指定当前使用的编译器的名称。其值可以为gc或gccgo。其中,gc编译器即为Go语言自带的编辑器,而gccgo编译器则为GCC提供的Go语言编译器
    -gccgoflags 此标记用于指定需要传递给gccgo编译器或链接器的标记的列表
    -gcflags 此标记用于指定需要传递给go tool compile命令的标记的列表
    -installsuffix 为了使当前的输出目录与默认的编译输出目录分离,可以使用这个标记。此标记的值会作为结果文件的父目录名称的后缀。其实,如果使用了-race标记,这个标记会被自动追加且其值会为race。如果我们同时使用了-race标记和-installsuffix,那么在-installsuffix标记的值的后面会再被追加_race,并以此来作为实际使用的后缀
    -ldflags 此标记用于指定需要传递给go tool link命令的标记的列表
    -linkshared 此标记用于与-buildmode=shared一同使用。后者会使作为编译目标的非main代码包都被合并到一个动态链接库文件中,而前者则会在此之上进行链接操作
    -pkgdir 指定一个目录,并从改目录下加载编译好的.a 文件,并把编译可能产生新的 .a 文件放入到该目录中
    -tags 此标记用于指定在实际编译期间需要受理的编译标签(也可被称为编译约束)的列表
    -toolexec 此标记可以让我们去自定义在编译期间使用一些Go语言自带工具(如vet、asm等)的方式
    -tags
    例:编译debug版本

    go build -tags "debug"
    1
    注意:build.go 和 build_debug.go 的文件开头的 // +build debug 注释,这个就是你编译时的 tags

    main.go

    package main
    func main() {
    tBuildTag()
    }

    build.go

    // +build !debug

    package main

    import "fmt"

    func tBuildTag() {
    fmt.Println("no debug")
    }

    build_debug.go

    // +build debug

    package main

    import "fmt"

    func tBuildTag() {
    fmt.Println("debug")
    }

    -ldflags ‘flag list’
    '-s -w': 压缩编译后的体积
    -s: 去掉符号表
    -w: 去掉调试信息,不能gdb调试了
    -X: 设置包中的变量值

    例:编译的时候,带上编译的人的姓名

    go build -ldflags "-X main.Developer=zhangsan"
    1
    main.go

    package main

    import "fmt"

    var Developer string

    func main() {
    fmt.Println("Developer:", Developer)
    }

    执行编译好的程序,可以看到 Developer: zhangsan 输出。

    -race
    go run -race 是不会进行竞态检测的。需要先 go build -race,然后再执行编译好的文件。如下是一个竞态示例输出:

    ==================
    WARNING: DATA RACE
    Read at 0x00c0000c9ce0 by goroutine 8:
    container/list.(*List).remove()
    D:/Go/src/container/list/list.go:109 +0x119
    container/list.(*List).Remove()
    D:/Go/src/container/list/list.go:141 +0x27a
    commonTest/list.tList1.func2()
    F:/GoTest/GoTest/list/list.go:55 +0x10c

    Previous write at 0x00c0000c9ce0 by goroutine 7:
    container/list.(*List).insertValue()
    D:/Go/src/container/list/list.go:104 +0x10c
    container/list.(*List).PushBack()
    D:/Go/src/container/list/list.go:155 +0xc6
    commonTest/list.tList1.func1()
    F:/GoTest/GoTest/list/list.go:27 +0x92

    Goroutine 8 (running) created at:
    commonTest/list.tList1()
    F:/GoTest/GoTest/list/list.go:37 +0x1cb
    commonTest/list.Test()
    F:/GoTest/GoTest/list/entrance.go:4 +0x37
    main.main()
    F:/GoTest/GoTest/main.go:19 +0x32

    Goroutine 7 (finished) created at:
    commonTest/list.tList1()
    F:/GoTest/GoTest/list/list.go:25 +0x17e
    commonTest/list.Test()
    F:/GoTest/GoTest/list/entrance.go:4 +0x37
    main.main()
    F:/GoTest/GoTest/main.go:19 +0x32
    ==================
    google官方解释
    go build 命令介绍
    go build命令详解
    “go build -X” 的妙用

    golang项目中使用条件编译 - yuchen16 - 博客园 https://www.cnblogs.com/ksir16/p/9050721.html

    How to use conditional compilation with the go build tool – The acme of foolishness https://dave.cheney.net/2013/10/12/how-to-use-conditional-compilation-with-the-go-build-tool

    golang项目中使用条件编译

    C语言中的条件编译

    golang中没有类似C语言中条件编译的写法,比如在C代码中可以使用如下语法做一些条件编译,结合宏定义来使用可以实现诸如按需编译release和debug版本代码的需求

    #ifndef
    #define
    ...
    
    #end

    golang中的条件编译

    golang支持两种条件编译的实现方式

    • build tags
    • 文件后缀

    1. 通过Build tags实现

    build tags 是通过代码注释的形式实现的,要写在文件的最顶端;

    go build指令在编译项目的时候会检查每一个文件的build tags,用来决定是编译还是跳过该文件

    build tags遵循以下规则

    1. 不同tag域之间用空格区分,他们是OR关系
    2. 同一tag域之内不同的tag用都好区分,他们是AND关系
    3. 每一个tag都由字母和数字构成,!开头表示条件“非”

    示例:

    // +build darwin freebsd netbsd openbsd

    约束此文件只能在支持kqueue的BSD系统上编译

    一个文件可能包含多行条件编译注释,比如:

    // +build linux darwin
    // +build 386

    约束该文件在linux/386 或 darwin/386平台编译

    需要注意的点

    tag注释和包声明必须用空行隔开,比如下面的写法是错误的,编译器会把第一行作为包说明来处理,而不是build tags

    1 // +build !linux
    2 package mypkg // wrong

    正确的写法如下:

    1 // +build !linux
    2 
    3 package mypkg // correct

    编译方法:

    只需要在go build指令后用-tags指定编译条件即可

    go build -tags linux

    2. 通过文件名后缀实现

    具有_$GOOS.go后缀的go文件在编译的时候会根据当前平台来判断是否将该文件导入并编译;同样适用于处理器架构判断 _$GOARCH.go

    两者可以结合起来使用,形式为: _$GOOS_$GOARCH.go

    示例:

    mypkg_freebsd_arm.go // 只在 freebsd/arm 编译
    mypkg_plan9.go       // 只在 plan9 编译

    文件名必须提供,如果只由后缀的文件名会被编译器忽略,比如:

    _linux.go
    _freebsd_386.go

    这两个文件会被编译器忽略,因为以下划线开头的文件都会被忽略

    How to use conditional compilation with the go build tool

    When developing Go packages that rely on specific features of the underlying platform or processor it is often necessary to provide a specialised implementation.

    Go does not have a preprocessor, a macro system, or a #define declaration to control the inclusion of platform specific code. Instead a system of tags and naming convention defined in the go/build package and supported by the go tool allows Go packages to customise themselves for the specific platform they are being compiled for.

    This post explains how conditional compilation is implemented and show you how you can use it in your projects.

    But first, go list

    Before we can talk about conditional compilation, we need to learn a little bit about the go list command. go list gives you access to the internal data structures which power the build process.

    go list takes the most of the same arguments as go buildtest, and install but does not perform any compilation. Using the -f, format flag we can supply a snippet of text/template code which is executed in a context containing a go/build.Package structure.

    Using the format flag, we can ask go list to tell us the names of the files that would be compiled.

    % go list -f '{{.GoFiles}}' os/exec
    [exec.go lp_unix.go]

    In the example above I asked for the list of files in os/exec package that would be compiled on this linux/arm system. The result is two files, exec.go which contains the common code shared across all platforms, and lp_unix.go while contains an implementation of exec.LookPath for unix-like systems.

    If I were to run the same command on a Windows system, the result would be

    C:go> go list -f '{{.GoFiles}}' os/exec
    [exec.go lp_windows.go]

    This short example demonstrates the two parts of the Go conditional compilation system, known as Build Constraints, which we will now explore in more detail.

    Build tags

    The first method of conditional compilation is via an annotation in the source code, commonly known as a build tag.

    Build tags are implemented as comments and should appear as close to the top of the file as possible.

    When go build is asked to build a package it will analyse each source file in the package looking for build tags. These tags control whether go build will pass the file to the compiler.

    A build tags follow these three rules

    1. a build tag is evaluated as the OR of space-separated options
    2. each option evaluates as the AND of its comma-separated terms
    3. each term is an alphanumeric word or, preceded by !, its negation

    As an example, the build tag found at the top of a source file

    // +build darwin freebsd netbsd openbsd

    would constrain this file to only building on BSD systems that supported kqueue.

    A file may have multiple build tags. The overall constraint is the logical AND of the individual constraints. For example

    // +build linux darwin
    // +build 386

    constrains the build to linux/386 or darwin/386 platforms only.

    A note about comments

    One thing that generally catches people out when they are first trying to make build tags work is this

    // +build !linux
    package mypkg // wrong

    In this example there is no newline separating the build tag and the package declaration. Because of this the build tag is associated with the package declaration as a comment describing the package and thus ignored.

    // +build !linux
    
    package mypkg // correct

    This is the correct form, a comment with a trailing newline stands alone and is not associated with any declaration and go vet will detect the missing newline.

    % go vet mypkg
    mypkg.go:1: +build comment appears too late in file
    exit status 1

    When this feature was added to go vet it detected several mistakes in the standard library and sub repos, so don’t feel bad if you get it wrong the first time.

    For reference, here is a sample showing a licence preamble, a build tag, and a package declaration

    % head headspin.go 
    // Copyright 2013 Way out enterprises. All rights reserved.
    // Use of this source code is governed by a BSD-style
    // license that can be found in the LICENSE file.
    
    // +build someos someotheros thirdos,!amd64
    
    // Package headspin implements calculates numbers so large
    // they will make your head spin.
    package headspin

    File suffixes

    The second option for providing conditional compilation is the name of the source file itself. This scheme is simpler than build tags, and allows the go/build package to exclude files without having to process the file.

    The naming convention is described in the documentation for the go/build package. Simply put, if your source file includes the suffix, _$GOOS.go then it will only be built on that platform. All other platforms will behave as if the file is not present. The same applies for _$GOARCH.go. The two can be combined as _$GOOS_$GOARCH.go, but not _$GOARCH_$GOOS.go.

    Some examples of file suffixes are,

    mypkg_freebsd_arm.go // only builds on freebsd/arm systems
    mypkg_plan9.go       // only builds on plan9

    Your source files still require a name, a suffix is not sufficient, for example

    _linux.go
    _freebsd_386.go

    will be ignored, even on linux or freebsd systems, because the go/build package ignores any file beginning with a period or an underscore.

    Choosing between build tags and file suffixes

    Build tags and file suffixes overlap in fuctionality. For example, a file called mypkg_linux.go that contained the build tag // +build linux is redundant.

    In general, when choosing between a build tag or a file suffix, you should choose a file suffix when there is an exact match between the platform or architecture and the file you want to include. eg,

    mypkg_linux.go         // only builds on linux systems
    mypkg_windows_amd64.go // only builds on windows 64bit platforms

    Conversely if your file is applicable to more than one platform or architecture, or you need to exclude a specific platform, a build tag should be used. eg,

    % grep '+build' $HOME/go/src/pkg/os/exec/lp_unix.go 
    // +build darwin dragonfly freebsd linux netbsd openbsd

    builds on all unix like platforms.

    % grep '+build' $HOME/go/src/pkg/os/types_notwin.go 
    // +build !windows

    builds on all platforms except Windows.

    Wrapping up

    While this post has focused only on Go source files, build tags and file suffixes can be used with any source file that the go tool can build. This includes .c and .s files. The Go standard library, specifically the runtimesyscallos and net packages contain great examples, I recommend studying them.

    Test files also support build tags and file suffixes and behave in the same manner as Go source files, conditionally including test cases on a per platform basis. Again the standard library contains many great examples.

    Finally, while the title of this article talks about the go tool, the conditional compilation features are not limited to just that tool. You can build your own tools to consume and analyse Go code with the same file suffix and build tag semantics using the go/build package.

    Posted in GoPhotography by Dave Cheney · Tags: 

     

     

     

  • 相关阅读:
    【语言处理与Python】6.3评估
    win10同时安装 office2016和visio2016
    如何学好C语言(转)
    数据库索引
    Redis系列(二)如何接受客户端请求并调用处理函数
    Redis系列(三)事件处理细节分析及epoll介绍
    linux下查看某一个程序所使用的内存方法总结
    c++ 二级指针详解&&hiredis api
    C风格字符串
    twemproxy简介
  • 原文地址:https://www.cnblogs.com/rsapaper/p/15511812.html
Copyright © 2011-2022 走看看