Justin Olbrantz
Justin Olbrantz

Reputation: 649

Why Are My Quotes Disappearing? (GNU make/sh)

I'm working with GNU makefiles on Windows at my work and trying to learn as I go. The recipe line that's giving me so much trouble is

$(SED) -n "/Format ID $(def_format_id)/,/End Format ID $(def_format_id)/ p" "$(def_format_altsec_header)" > "$(def_format_file)"

which fails for C:/GNU1_06/bin/sed: -e expression #1, char 7: unterminated address regex.

To try to understand the behavior that I've been banging my head against for the last couple hours, I changed it to a simple command to cause sed to launch and stall so I can look at exactly what's getting invoked with Process Explorer:

$(SED) -e s/blah//

ProcExp shows that make is directly invoking sed with the expected command line. If you single-quote the argument, however, make invokes EXACTLY the same thing (no quotes to be found on the command line).

Things get really strange when you use double-quotes. Make invokes C:/GNU1_06/bin/sh.exe -c "C:/GNU1_06/bin/sed -e \"s/blah//\"" So far so good, but then sh invokes C:\GNU1_06\bin\sed.exe -e s/blah// as if the escaped quotes were never there.

What exactly is going on here? Why are my quotes disappearing into the nether before sed ever gets to run?

UPDATE: This appears to be related to the fact that $(SED) is a fully-specified path. This behavior is not observed when sed.exe is used alone (and ProcExp proves that that uses the same copy of sed as the fully-specified path).

This problem reproduces in the minimal makefile

.PHONY: all
all:
    C:/gnu1_06/bin/sed.exe -n "/Format ID 01010101/,/End Format ID 01010101/ p" "./FORMAT/BIGHILO/AC/99/sff_altsec_01_data.h"

Upvotes: 1

Views: 324

Answers (1)

bobbogo
bobbogo

Reputation: 15483

When make decides to rebuild a target it expands the recipe, and then passes each line in the result separately to a new invocation of the the shell.

Except that, as an optimisation, there is no need to pass it to the shell when the line contains no meta characters (i.e., characters that would be specially interpreted by the shell, things like <, >, ", & etc.). In this case make just executes the line directly. AFAICT this list is not documented.

Personally, when on windows, I use cygwin make exclusively. Why? Because it is much more compatible in all these sorts of corner cases. I once got to a place with mingw make where 5 backslashes were not enough, and 6 were too many. Ugh!

Note also that command-line parsing in windows is insane. When does the echo built into cmd.exe remove double quotes? Trust me, cygwin 'just works'™ (parallel building is worth price of entry alone).

Upvotes: 1

Related Questions