title: generate build timestamp in Go
body: <p>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 <code>git commit</code>.</p>
  
  <p>In a C program (FWIW my <a href="http://github.com/bstarynk/bismon/" rel="noreferrer">bismon</a> project is doing something very similar), I would just generate some <code>_timestamp.c</code> file, e.g. with a <code>Makefile</code> recipe like:</p>
  
  <pre><code>_timestamp.c: 
      date +'const char my_timestamp[]='%c';%n' &gt; $@
      (echo -n 'const char my_lastgitcommit[]="'; \
       git log --format=oneline --abbrev=12 --abbrev-commit -q | head -1 \
         | tr -d '\n\r\f\"\\\\' ; echo '";') &gt;&gt; $@
  </code></pre>
  
  <p>and I would link my program <code>myprog</code> with something like:</p>
  
  <pre><code>myprog: $(MYOBJECTS) _timestamp.c
      $(LINK.c) $(MYOBJECTS) _timestamp.c -o $@
      $(RM) _timestamp.c
  </code></pre>
  
  <p>Notice that <code>_timestamp.c</code> is automatically removed at each successful link. Of course in some header I would declare <code>extern const char my_timestamp[];</code> and <code>extern const char my_lastgitcommit[]:</code> and I would use e.g. <code>my_timestamp</code> and <code>my_lastgitcommit</code> in my <code>main.c</code> (and have <code>MYOBJECTS</code> contain <code>main.o</code>)</p>
  
  <p>It looks like <a href="https://golang.org/cmd/go/" rel="noreferrer"><code>go generate</code></a> could be used to behave in a similar way. I would like to have a package <code>"timestamp"</code> defining two string globals <code>timestamp.My_timestamp</code> and <code>timestamp.My_gitcommit</code>  but I don't exactly understand how to do it.</p>
  
  <p>I tried to add some <code>timestamp/timestamp.go</code> file with</p>
  
  <pre><code>package timestamp
  
  //go:generate date +'var My_timestamp = "%c"%n'
  
  // Code generated - DO NOT EDIT.
  </code></pre>
  
  <p>But it did not change with <code>go generate</code> then <code>go install</code></p>
  
  <p>Of course, these timestamps should be constant strings at compile time, and I expect to find them when running the <a href="http://man7.org/linux/man-pages/man1/strings.1.html" rel="noreferrer">strings(1)</a> utility on the ELF executable.</p>
  
  <p>BTW, I recall one of the motivations of <a href="https://golang.org/doc/articles/go_command.html" rel="noreferrer">the <code>go</code> command</a>:</p>
  
  <blockquote>
    <p>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.</p>
  </blockquote>
  
  <p>So I am still expecting something to go into the source code alone, without extra configuration for building.</p>
  
  <p>In other words, I want to <em>generate</em> at every build a Go file similar to:</p>
  
  <pre><code>// generated timestamp.go file
  package timestamp
  var Buildtime = "Tue 30 Oct 2018 09:39:01 AM MET";
  var Buildlastgitcommit = "7fde394b60bc adding timestamp.go"
  </code></pre>
  
  <p>The <code>Buildtime</code> string is generated by <code>date +%c</code>. The <code>Buildlastgitcommit</code> string might be generated by commands similar to what my <code>_timestamp.c</code> make rule is doing.</p>
  
  <p>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 <em>usual</em> commands, either without extra arguments to <code>go build</code> or any other build automation tool, or with some way to fail the build if the mandatory arguments are forgotten; hence <a href="https://stackoverflow.com/a/53045029/841108">atanayel's answer</a> is not enough). So I want the <a href="http://man7.org/linux/man-pages/man1/strings.1.html" rel="noreferrer">strings(1)</a> 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.</p>
  
  <p>I could consider switching to some other, <em>Go-friendly</em>, <a href="https://en.wikipedia.org/wiki/Build_automation" rel="noreferrer">build automation</a> system (but it seems that even with <a href="https://getgb.io/" rel="noreferrer">gb</a> I can't easily do what I want: quickly generate some simple <code>.go</code> file at every build). But I don't understand why it is so difficult to use <em>generated</em> Go files in Go programs. Generating simple code is following the <a href="https://en.wikipedia.org/wiki/Unix_philosophy" rel="noreferrer">Unix philosophy</a>, and has been practiced since many decades (e.g. see <a href="https://godoc.org/golang.org/x/tools/cmd/goyacc" rel="noreferrer">goyacc</a> inspired by the old <a href="https://en.wikipedia.org/wiki/Yacc" rel="noreferrer">yacc</a> program).</p>
  
  <p>NB: the <a href="https://docs.google.com/document/d/1V03LUfjSADDooDMhe-_K59EgpTEm3V8uvQRuNMAEnjg/edit" rel="noreferrer">rationale for <code>go generate</code></a> explicitly mentions that:</p>
  
  <blockquote>
    <p>It is not a goal of this proposal to build a generalized build system like the Unix <code>make(1)</code> utility. </p>
  </blockquote>
  
  <p>and later </p>
  
  <blockquote>
    <p>once things are settled, the author commits the generated files to the source repository, </p>
  </blockquote>
  
  <p>(and this is <em>not</em> my use case)</p>
  
  <p>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 <a href="https://docs.google.com/document/d/1V03LUfjSADDooDMhe-_K59EgpTEm3V8uvQRuNMAEnjg/edit" rel="noreferrer"><code>go</code> command motivation</a> explains), in my particular case, I <em>do</em> need some build automation tool. In my <a href="https://gitlab.com/bstarynk/bastawigo" rel="noreferrer">bastawigo</a> toy project (GPLv3+), I am using <code>make</code> (driving the <code>go</code> command)</p>