使用Makefile创建golang项目

为什么使用makefiles

  • build != complie

    -a 构建一个项目意味着更多比编译你的代码

    -b 静态分析,lint检查,安装,配置,打包......

  • 项目的各个阶段都有相同的工具

    -a Makefiles作为胶水的角色连接 起go编译链(build, install, clean)
    -b 同时也可以使用第三方工具(go lint, go vet, gb, 等等......)

  • 不确定语言

    -a 有可能你的项目可能不止依赖仅仅一种语言
    -b 生成配置文件,指导页,固定数据等等......

  • 可以在多个平台上使用

    -a 用户可以选择任何他想用的系统
    -b 夸平台编译

code to build

  1. package main
  2. import "fmt"
  3. func main() {
  4. // Probably the most awesome piece of code you've ever seen.
  5. fmt.Println("i love you!")
  6. }

Makefile

  1. default:
  2. go build

Run

  1. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:24:29]
  2. → ls -al
  3. total 16
  4. drwxr-xr-x 4 aliasliyu4 staff 136 Feb 14 13:24 .
  5. drwxr-xr-x 23 aliasliyu4 staff 782 Feb 14 13:22 ..
  6. -rw-r--r-- 1 aliasliyu4 staff 21 Feb 14 13:23 Makefile
  7. -rw-r--r-- 1 aliasliyu4 staff 134 Feb 14 13:23 main.go
  8. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:24:31]
  9. → make
  10. go build
  11. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:24:32]
  12. → ls
  13. Makefile gomake main.go
  14. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:24:34]
  15. → ./gomake
  16. i love you!
  17. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:24:36]

简单和兼容的编译,安装,清除。

编译: 输入:"make"

  • 懒癌有救!这样就可以输入的更少较之输入"go build package"
  • 你也可以编译多个项目在单个Makefile中。

    -a 一个Makefile可以调用另一个Makefile

  • 想要在你的代码中使用更多复杂的工具?

    -a 构建一个项目的所有脚本和数据都属于它本身
    -b 如果有你不想持续集成的部分,只需要改变你的Makefile

安装: 输入:"make install"

  1. 大多数的时候只"go install package" 是不够的,因为在创建了二进制文件之后这里可能还有其他的步骤要做!
  2. 生成配置文件,指导页,固定数据等等......
  3. 不是你所依赖的都步骤,只需要改变Makefile

清理: 输入:"make clean"

  1. 清理你的项目不只是仅仅删除老的二进制文件这么多。

Improved Make file

  1. # Default target: builds the project
  2. build:
  3. go build
  4. # Installs our project: copies binaries
  5. install:
  6. go install
  7. # Cleans our project: deletes binaries
  8. clean:
  9. go clean

Run

  1. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:51:49]
  2. → ls -al
  3. total 16
  4. drwxr-xr-x 4 aliasliyu4 staff 136 Feb 14 13:51 .
  5. drwxr-xr-x 23 aliasliyu4 staff 782 Feb 14 13:22 ..
  6. -rw-r--r-- 1 aliasliyu4 staff 175 Feb 14 13:50 Makefile
  7. -rw-r--r-- 1 aliasliyu4 staff 134 Feb 14 13:23 main.go
  8. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:51:53]
  9. → make
  10. go build
  11. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:51:57]
  12. → ls
  13. Makefile gomake main.go
  14. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:52:05]
  15. → ./gomake
  16. i love you!
  17. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:52:14]
  18. → make clean
  19. go clean
  20. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [13:52:20]
  21. → ls
  22. Makefile main.go

使用编译期间的变量做一些琐事(1)

  1. 添加版本号
  2. 添加构建时间

Improved source code

  1. package main
  2. import "fmt"
  3. // Variables to identify the build
  4. var (
  5. Version = "1.0.0"
  6. Build = "2017-02-14"
  7. )
  8. func main() {
  9. fmt.Println("Version: ", Version)
  10. fmt.Println("Build time: ", Build)
  11. }

Improved Makefile

  1. # This how we want to name the binary output
  2. BINARY=gomake
  3. # Builds the project
  4. build:
  5. go build -o ${BINARY}
  6. # Installs our project: copies binaries
  7. install:
  8. go install
  9. # Cleans our projects: deletes binaries
  10. clean:
  11. if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
  12. .PHONY: clean install

Run

  1. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:22:46]
  2. → ls -al
  3. total 16
  4. drwxr-xr-x 4 aliasliyu4 staff 136 Feb 14 14:22 .
  5. drwxr-xr-x 23 aliasliyu4 staff 782 Feb 14 13:22 ..
  6. -rw-r--r-- 1 aliasliyu4 staff 292 Feb 14 14:22 Makefile
  7. -rw-r--r-- 1 aliasliyu4 staff 203 Feb 14 14:03 main.go
  8. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:22:49]
  9. → make
  10. go build -o gomake
  11. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:22:51]
  12. → ls -al
  13. total 3152
  14. drwxr-xr-x 5 aliasliyu4 staff 170 Feb 14 14:22 .
  15. drwxr-xr-x 23 aliasliyu4 staff 782 Feb 14 13:22 ..
  16. -rw-r--r-- 1 aliasliyu4 staff 292 Feb 14 14:22 Makefile
  17. -rwxr-xr-x 1 aliasliyu4 staff 1603664 Feb 14 14:22 gomake
  18. -rw-r--r-- 1 aliasliyu4 staff 203 Feb 14 14:03 main.go
  19. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:22:54]
  20. → ./gomake
  21. Version: 1.0.0
  22. Build time: 2017-02-14
  23. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:22:58]
  24. → make clean
  25. if [ -f gomake ] ; then rm gomake ; fi
  26. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:23:04]
  27. → ls -al
  28. total 16
  29. drwxr-xr-x 4 aliasliyu4 staff 136 Feb 14 14:23 .
  30. drwxr-xr-x 23 aliasliyu4 staff 782 Feb 14 13:22 ..
  31. -rw-r--r-- 1 aliasliyu4 staff 292 Feb 14 14:22 Makefile
  32. -rw-r--r-- 1 aliasliyu4 staff 203 Feb 14 14:03 main.go

使用编译期间的变量做一些琐事(2)

  • 增加版本号

    -a 编辑代码去突出版本号是痛苦的事情。
    -b 你很快就会忘记它,提交,然后你的git历史也会断裂

  • 添加构建时间

    -a 和上述的版本号问题相似。
    -b 使用哪种格式化的时间戳呢?怎么有这么奇怪的字符串?
    -c 显然在编译之前也需要一个时钟去检查时间的准确性。

Improved source code

  1. package main
  2. import "fmt"
  3. // Variables to identify the build
  4. var (
  5. Version string
  6. Build string
  7. )
  8. func main() {
  9. fmt.Println("Version: ", Version)
  10. fmt.Println("Build time: ", Build)
  11. }

Improved Makefile

  1. # This how we want to name the binary output
  2. BINARY=gomake
  3. # These are the values we want to pass for VERSION and BUILD
  4. VERSION=1.0.0
  5. BUILD=`date +%FT%T%z`
  6. # Setup the -Idflags options for go build here,interpolate the variable values
  7. LDFLAGS=-ldflags "-X main.Version=${VERSION} -X main.Build=${BUILD}"
  8. # Builds the project
  9. build:
  10. go build ${LDFLAGS} -o ${BINARY}
  11. # Installs our project: copies binaries
  12. install:
  13. go install ${LDFLAGS}
  14. # Cleans our projects: deletes binaries
  15. clean:
  16. if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
  17. .PHONY: clean install

Run

  1. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:59:14]
  2. → ls -al
  3. total 3152
  4. drwxr-xr-x 5 aliasliyu4 staff 170 Feb 14 14:59 .
  5. drwxr-xr-x 23 aliasliyu4 staff 782 Feb 14 13:22 ..
  6. -rw-r--r-- 1 aliasliyu4 staff 562 Feb 14 14:59 Makefile
  7. -rwxr-xr-x 1 aliasliyu4 staff 1603728 Feb 14 14:58 gomake
  8. -rw-r--r-- 1 aliasliyu4 staff 192 Feb 14 14:53 main.go
  9. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:59:17]
  10. → make
  11. go build -ldflags "-X main.Version=1.0.0 -X main.Build=`date +%FT%T%z`" -o gomake
  12. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:59:18]
  13. → ./gomake
  14. Version: 1.0.0
  15. Build time: 2017-02-14T14:59:18+0800
  16. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:59:23]
  17. → make clean
  18. if [ -f gomake ] ; then rm gomake ; fi
  19. # aliasliyu4 at alialliyu4.local in ~/svn/src/gomake [14:59:28]
  20. → ls -al
  21. total 16
  22. drwxr-xr-x 4 aliasliyu4 staff 136 Feb 14 14:59 .
  23. drwxr-xr-x 23 aliasliyu4 staff 782 Feb 14 13:22 ..
  24. -rw-r--r-- 1 aliasliyu4 staff 562 Feb 14 14:59 Makefile

使用编译期间的变量做一些琐事(3)

  • 使用LDFLAGS

    -a go链接命令允许你去设置字符串变量在编译的时候使用-X选项

    -b 使用格式化:importpath.name=value

  • golang1.5+和之前版本的不同

    -a golang1.5+ -X 选项作为一个分隔参数在“k=v”之间
    -b 譬如: go build -ldflags "-X main.Version=1.0.0 -X main.Build=2017-02-14"
    -c golang < 1.5 -X选项后面跟着两个分隔的参数
    -d 譬如: go build -idflags "-X main.Version 1.0.0 -X main.Build 2017-02-14"

github
开发者头条
Makefile
main.go
未完待续......