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

Re: [RFC PATCH] Move SHA-1 implementation selection into a header file

From
brian m. carlson <sandals@crustytoothpaste.net>
Date
Mar 12, 2017, 16:51 UTC
Message-ID
<20170312165119.3eokqse4uxdet6yd@genre.crustytoothpaste.net>
In-Reply-To
<20170312130149.czir5hcbosqlmkhb@sigill.intra.peff.net>
On Sun, Mar 12, 2017 at 09:01:49AM -0400, Jeff King wrote:
Show 26 quoted lines
> On Sat, Mar 11, 2017 at 10:28:18PM +0000, brian m. carlson wrote:
> 
> > Many developers use functionality in their editors that allows for quick
> > syntax checks, including warning about questionable constructs.  This
> > functionality allows rapid development with fewer errors.  However, such
> > functionality generally does not allow the specification of
> > project-specific defines or command-line options.
> > 
> > Since the SHA1_HEADER include is not defined in such a case, developers
> > see spurious errors when using these tools.  Furthermore, while using a
> > macro as the argument to #include is permitted by C11, it isn't
> > permitted by C89 and C99, and there are known implementations which
> > reject it.
> > 
> > Instead of using SHA1_HEADER, create a hash.h header and use #if
> > and #elif to select the desired header.  Have the Makefile pass an
> > appropriate option to help the header select the right implementation to
> > use.
> 
> This has bit me once or twice in the past[1], too, so I'm happy to see
> somebody tackling it.
> 
> Your solution does mean that your tool, whatever it is, that runs
> without the same CFLAGS as the Makefile may get a _different_ sha1
> implementation, though. That's probably good enough for some purposes
> but perhaps not for others.

Yeah, my goal was basically to pass -fsyntax-only, not to produce useful object files. My patch does basically require that the user have OpenSSL installed, but I do, so it doesn't matter.

I considered after the fact that I might just do something like:
  #ifdef SHA1_HEADER
  #include SHA1_HEADER
  #else
  #include "block-sha1/sha1.h"
  #endif
That would be the smallest change, but probably not the best.
> The "most correct" solution, I think, would be to stop using "-D" flags
> in favor of actually generating hash.h. Something like the patch
> below[2] (though I think it there are some rough edges with the
> dependencies).

I agree that's a better solution. I was concerned about avoiding ending up rebuilding everything when we regenerated the file, but it looks like you've avoided that with cmp.

Show 10 quoted lines
> Of course the sha1 header is just one of many such defines. It's the one
> that is most visible because the result is syntactically valid without
> it, but anything you compile without the Makefile's CFLAGS may be subtly
> different than what the Makefile would produce. So arguably the Makefile
> should be writing out a build-options.h with all of the values, and that
> should get pulled in by git-compat-util.h.
> 
> I don't know if we want to go down that rabbit hole or not. I offer it
> merely as an alternative. I'm OK with your patch as-is if you don't want
> to dump any more time into it.

I'll take this patch for now and fix it up with the comment I mentioned below. If someone wants to improve the situation down the line, then they can pick that up.

I assume I can apply your sign-off to the resulting patch?
Show 46 quoted lines
> -Peff
> 
> [1] I think I hit the problem when trying to debug some internal part of
>     git and writing a one-off "foo.c" that calls the code I want. You
>     can't compile it with "gcc foo.c".
> 
> [2] Here's what a patch for the generated-header might look like:
> 
> diff --git a/Makefile b/Makefile
> index 9f0eae428..0d65d50e9 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -690,6 +690,7 @@ XDIFF_LIB = xdiff/lib.a
>  VCSSVN_LIB = vcs-svn/lib.a
>  
>  GENERATED_H += common-cmds.h
> +GENERATED_H += hash.h
>  
>  LIB_H = $(shell $(FIND) . \
>  	-name .git -prune -o \
> @@ -1639,8 +1640,7 @@ PERLLIB_EXTRA_SQ = $(subst ','\'',$(PERLLIB_EXTRA))
>  # from the dependency list, that would make each entry appear twice.
>  LIBS = $(filter-out %.o, $(GITLIBS)) $(EXTLIBS)
>  
> -BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \
> -	$(COMPAT_CFLAGS)
> +BASIC_CFLAGS += $(COMPAT_CFLAGS)
>  LIB_OBJS += $(COMPAT_OBJS)
>  
>  # Quote for C
> @@ -1781,7 +1781,7 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)
>  	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
>  		$(filter %.o,$^) $(LIBS)
>  
> -help.sp help.s help.o: common-cmds.h
> +help.sp help.s help.o: common-cmds.h hash.h
>  
>  builtin/help.sp builtin/help.s builtin/help.o: common-cmds.h GIT-PREFIX
>  builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
> @@ -1805,6 +1805,10 @@ common-cmds.h: generate-cmdlist.sh command-list.txt
>  common-cmds.h: $(wildcard Documentation/git-*.txt)
>  	$(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt >$@+ && mv $@+ $@
>  
> +hash.h:
> +	$(QUIET_GEN)echo '#include $(SHA1_HEADER)' >$@+ && \
> +	{ cmp $@+ $@ >/dev/null 2>/dev/null || mv $@+ $@; }

I think here we'd want to also "rm -f $@+", so that we don't leave an extra file behind if we're up-to-date (which is the common case), much like we do for GIT-BUILD-OPTIONS.

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 832 623 2791 | https://www.crustytoothpaste.net/~bmc | My opinion only
OpenPGP: https://keybase.io/bk2204
Previous: Jeff KingNext: Jeff King
Message 3 of 16 in “Move SHA-1 implementation selection into a header file”
  1. Move SHA-1 implementation selection into a header filebrian m. carlson, Mar 11, 2017
  2. Jeff KingMar 12, 2017
  3. brian m. carlsonMar 12, 2017
  4. Jeff KingMar 12, 2017
  5. Junio C HamanoMar 12, 2017
  6. Jonathan NiederMar 14, 2017
  7. Jeff KingMar 14, 2017
  8. Junio C HamanoMar 14, 2017
  9. Jeff KingMar 14, 2017
  10. Jonathan NiederMar 14, 2017
  11. Ramsay JonesMar 14, 2017
  12. brian m. carlsonMar 14, 2017
  13. Ramsay JonesMar 15, 2017
  14. Junio C HamanoMar 15, 2017
  15. Ramsay JonesMar 15, 2017
  16. Jonathan NiederMar 14, 2017

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.