git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 11/13] Makefile: auto-build C strings from make variables

From
Jeff King <peff@peff.net>
Date
Feb 5, 2014, 18:02 UTC
Message-ID
<20140205180206.GK15218@sigill.intra.peff.net>
In-Reply-To
<20140205174823.GA15070@sigill.intra.peff.net>

We already insert the values of some make variables into files in MAKE/*. We can therefore build a simple pattern rule for converting such a value into a C string in a header file, which can then be included and used as normal.

The new system is demonstrated on version.c, where it can replace the use of "-D" on the command-line. Note that we still have to manually specify a dependency in the Makefile. In an ideal world, we would auto-detect the header dependency; however, there are two holdups:

  1. We cannot rely on having automatic header dependency
     generation on all platforms.
  2. Even when we do generate the dependencies, we rely on
     being able to compile the file once, which means our
     system cannot handle generated headers without a manual
     dependency to bootstrap it.
Signed-off-by: Jeff King <peff@peff.net>
---
This is a technique that I have used in other projects with great
success, as the make variable dependencies are represented as file
dependencies (which is the only type of dependency make knows about).

_But_ it ends up a lot less nice here because of the way we do auto-dependencies. I'm totally open to revamping the way we handle our header dependencies, but I didn't do that in this series.

 Makefile         | 11 +++++++----
 script/mkcstring | 18 ++++++++++++++++++
 version.c        |  6 ++++--
 3 files changed, 29 insertions(+), 6 deletions(-)
 create mode 100644 script/mkcstring
diff --git a/Makefile b/Makefile
index cd07a70..203171d 100644
--- a/Makefile
+++ b/Makefile
@@ -1593,6 +1593,11 @@ MAKE/$1: FORCE
 	fi
 endef
 
+MAKE/%-string.h: MAKE/% script/mkcstring
+	$(QUIET_GEN)$(SHELL_PATH) script/mkcstring \
+		$(subst -,_,$*) <$< >$@+ && \
+		mv $@+ $@
+
 LIBS = $(GITLIBS) $(EXTLIBS)
 
 BASIC_CFLAGS += -DSHA1_HEADER=$(call sq,$(SHA1_HEADER)) \
@@ -1614,6 +1619,7 @@ BASIC_CFLAGS += -DSHELL_PATH=$(call scq,$(SHELL_PATH))
 endif
 
 $(eval $(call make-var,USER-AGENT,user agent string,$(GIT_USER_AGENT)))
+$(eval $(call make-var,VERSION,version,$(GIT_VERSION)))
 
 ifdef DEFAULT_HELP_FORMAT
 BASIC_CFLAGS += -DDEFAULT_HELP_FORMAT='"$(DEFAULT_HELP_FORMAT)"'
@@ -1713,10 +1719,7 @@ builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
 	-DGIT_MAN_PATH=$(call scq,$(mandir_relative)) \
 	-DGIT_INFO_PATH=$(call scq,$(infodir_relative))
 
-version.sp version.s version.o: GIT-VERSION-FILE MAKE/USER-AGENT
-version.sp version.s version.o: EXTRA_CPPFLAGS = \
-	-DGIT_VERSION=$(call scq,$(GIT_VERSION)) \
-	-DGIT_USER_AGENT=$(call scq,$(GIT_USER_AGENT))
+version.sp version.s version.o: MAKE/VERSION-string.h MAKE/USER-AGENT-string.h
 
 $(BUILT_INS): git$X
 	$(QUIET_BUILT_IN)$(RM) $@ && \
diff --git a/script/mkcstring b/script/mkcstring
new file mode 100644
index 0000000..c01f430
--- /dev/null
+++ b/script/mkcstring
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+name=$1; shift
+
+c_quote() {
+	sed 's/\\/\\\\/g; s/"/\\"/'
+}
+
+cat <<-EOF
+#ifndef MAKE_${name}_H
+#define MAKE_${name}_H
+
+/* Auto-generated by mkcstring */
+
+#define MAKE_${name} "$(c_quote)"
+
+#endif /* MAKE_${name}_H */
+EOF
diff --git a/version.c b/version.c
index 6106a80..f68a93b 100644
--- a/version.c
+++ b/version.c
@@ -1,8 +1,10 @@
 #include "git-compat-util.h"
 #include "version.h"
 #include "strbuf.h"
+#include "MAKE/USER-AGENT-string.h"
+#include "MAKE/VERSION-string.h"
 
-const char git_version_string[] = GIT_VERSION;
+const char git_version_string[] = MAKE_VERSION;
 
 const char *git_user_agent(void)
 {
@@ -11,7 +13,7 @@ const char *git_user_agent(void)
 	if (!agent) {
 		agent = getenv("GIT_USER_AGENT");
 		if (!agent)
-			agent = GIT_USER_AGENT;
+			agent = MAKE_USER_AGENT;
 	}
 
 	return agent;
-- 
1.8.5.2.500.g8060133
Previous: Junio C HamanoNext: Junio C Hamano
Message 18 of 28 in “makefile refactoring”
  1. 0/13 makefile refactoringJeff King, Feb 5, 2014
  2. 01/13 Makefile: drop USE_GETTEXT_SCHEME from GIT-CFLAGSJeff King, Feb 5, 2014
  3. 02/13 Makefile: fix git-instaweb dependency on gitwebJeff King, Feb 5, 2014
  4. 03/13 Makefile: introduce make-var helper functionJeff King, Feb 5, 2014
  5. Eric SunshineFeb 6, 2014
  6. 04/13 Makefile: use tempfile/mv strategy for GIT-*Jeff King, Feb 5, 2014
  7. 05/13 Makefile: prefer printf to echo for GIT-*Jeff King, Feb 5, 2014
  8. 06/13 Makefile: store GIT-* sentinel files in MAKE/Jeff King, Feb 5, 2014
  9. Junio C HamanoFeb 5, 2014
  10. 07/13 Makefile: always create files via make-varJeff King, Feb 5, 2014
  11. 08/13 Makefile: introduce sq function for shell-quotingJeff King, Feb 5, 2014
  12. Junio C HamanoFeb 5, 2014
  13. 09/13 Makefile: add c-quote helper functionJeff King, Feb 5, 2014
  14. Junio C HamanoFeb 5, 2014
  15. Jeff KingFeb 5, 2014
  16. 10/13 Makefile: drop *_SQ variablesJeff King, Feb 5, 2014
  17. Junio C HamanoFeb 5, 2014
  18. 11/13 Makefile: auto-build C strings from make variablesJeff King, Feb 5, 2014
  19. Junio C HamanoFeb 5, 2014
  20. Jeff KingFeb 5, 2014
  21. 12/13 Makefile: teach scripts to include make variablesJeff King, Feb 5, 2014
  22. Junio C HamanoFeb 5, 2014
  23. Jeff KingFeb 5, 2014
  24. Thomas RastFeb 8, 2014
  25. Jeff KingFeb 10, 2014
  26. 13/13 move LESS/LV pager environment to MakefileJeff King, Feb 5, 2014
  27. Jeff KingFeb 5, 2014
  28. Jeff KingFeb 5, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.