dongsui4658 2018-10-28 11:33
浏览 148

在Go中生成构建时间戳

I want in a Go program (using Go 1.11.1 on Debian/Linux/x86-64) to keep the build timestamp with a line explaining the last git commit.

In a C program (FWIW my bismon project is doing something very similar), I would just generate some _timestamp.c file, e.g. with a Makefile recipe like:

_timestamp.c: 
    date +'const char my_timestamp[]='%c';%n' > $@
    (echo -n 'const char my_lastgitcommit[]="'; \
     git log --format=oneline --abbrev=12 --abbrev-commit -q | head -1 \
       | tr -d '
\f\"\\\\' ; echo '";') >> $@

and I would link my program myprog with something like:

myprog: $(MYOBJECTS) _timestamp.c
    $(LINK.c) $(MYOBJECTS) _timestamp.c -o $@
    $(RM) _timestamp.c

Notice that _timestamp.c is automatically removed at each successful link. Of course in some header I would declare extern const char my_timestamp[]; and extern const char my_lastgitcommit[]: and I would use e.g. my_timestamp and my_lastgitcommit in my main.c (and have MYOBJECTS contain main.o)

It looks like go generate could be used to behave in a similar way. I would like to have a package "timestamp" defining two string globals timestamp.My_timestamp and timestamp.My_gitcommit but I don't exactly understand how to do it.

I tried to add some timestamp/timestamp.go file with

package timestamp

//go:generate date +'var My_timestamp = "%c"%n'

// Code generated - DO NOT EDIT.

But it did not change with go generate then go install

Of course, these timestamps should be constant strings at compile time, and I expect to find them when running the strings(1) utility on the ELF executable.

BTW, I recall one of the motivations of the go command:

An explicit goal for Go from the beginning was to be able to build Go code using only the information found in the source itself, not needing to write a makefile or one of the many modern replacements for makefiles. If Go needed a configuration file to explain how to build your program, then Go would have failed.

So I am still expecting something to go into the source code alone, without extra configuration for building.

In other words, I want to generate at every build a Go file similar to:

// generated timestamp.go file
package timestamp
var Buildtime = "Tue 30 Oct 2018 09:39:01 AM MET";
var Buildlastgitcommit = "7fde394b60bc adding timestamp.go"

The Buildtime string is generated by date +%c. The Buildlastgitcommit string might be generated by commands similar to what my _timestamp.c make rule is doing.

I need these strings to be constant and built-in the ELF executable produced by a Go build (which I would prefer to be done by usual commands, either without extra arguments to go build or any other build automation tool, or with some way to fail the build if the mandatory arguments are forgotten; hence atanayel's answer is not enough). So I want the strings(1) utility to find these strings quickly in the executable. And the generation of such files should be configured in some kind of files, not requiring extra arguments to builders.

I could consider switching to some other, Go-friendly, build automation system (but it seems that even with gb I can't easily do what I want: quickly generate some simple .go file at every build). But I don't understand why it is so difficult to use generated Go files in Go programs. Generating simple code is following the Unix philosophy, and has been practiced since many decades (e.g. see goyacc inspired by the old yacc program).

NB: the rationale for go generate explicitly mentions that:

It is not a goal of this proposal to build a generalized build system like the Unix make(1) utility.

and later

once things are settled, the author commits the generated files to the source repository,

(and this is not my use case)

PS. I only care about POSIX systems; I really don't care if my Go software cannot be built on Windows. And I tend to think that (contrarily to what go command motivation explains), in my particular case, I do need some build automation tool. In my bastawigo toy project (GPLv3+), I am using make (driving the go command)

  • 写回答

3条回答 默认 最新

  • douyanti2808 2018-10-29 10:48
    关注
    export LAST_BUILD=$(date +"%T") ; go build ...
    
    Os.Getenv("LAST_BUILD")
    
    评论

报告相同问题?

悬赏问题

  • ¥15 Stata 面板数据模型选择
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 请问这个是什么意思?
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用