Shell脚本用Sed修改Makefile默认目标失败及术语疑问
Sed替换Makefile默认目标失败的原因及术语澄清
Hey there! Let's tackle your two questions one by one—first why your Sed command isn't working on Ubuntu, then clear up the confusion about Make's default target terminology.
一、为什么Sed命令在Ubuntu中没修改Makefile?
Even if your regex works on regex testing tools, there are a few common pitfalls with GNU Sed (the version Ubuntu ships with) that might be tripping you up:
- Regex syntax differences: Most online regex tools use JavaScript-style regex, but GNU Sed defaults to POSIX Basic Regular Expressions (BRE). This means characters like
+,(), and|need to be escaped with a backslash (\+,\(\),\|) to behave as you expect. If you want to use syntax closer to what you tested, add the-Eflag to enable POSIX Extended Regular Expressions (ERE) in Sed. - Missing the in-place edit flag: By default, Sed only prints modified content to your terminal—it won't write changes back to the file automatically. To edit the Makefile directly, add the
-iflag (GNU Sed doesn't require an empty string after-i, unlike BSD Sed). For example:sed -i 's/your-regex/your-replacement/' Makefile - Hidden whitespace mismatches: Makefiles are picky about whitespace—target lines might use tabs instead of spaces, or have trailing spaces your regex isn't accounting for. Run
cat -A Makefileto see invisible characters like tabs (^I) and newlines, then adjust your regex to match exactly. - Regex targeting the wrong line: The default Make target is the first non-comment, non-empty line in the file. If your regex skips over comments/blank lines or matches later targets, it won't modify the actual default target.
二、Make的默认目标是main还是main.c?
Great question—let's break down the terminology clearly:
- The default target is the first non-comment, non-empty target defined in your Makefile. The target name is whatever you write before the colon.
- If your Makefile starts with
main: main.c, the default target ismain(this is the standard case—mainis the executable you're building). - If your first target was something like
main.c: generated-header.h, the default target would bemain.c(though this is uncommon, since you rarely generate source files as a primary target).
- If your Makefile starts with
- A common best practice is to define an
alltarget as the first entry, which depends on your final executable(s). This makes your Makefile more flexible—for example:
Here, runningall: main main: main.c gcc -o main main.c clean: rm -f mainmakewithout arguments will buildmain(sinceallis the default target and depends onmain).
As a quick working example, if you want to replace the first default target with new_target, this GNU Sed command (using ERE for cleaner syntax) should do the trick:
sed -i -E '1,/^[^#[:space:]]/{s/^([^#[:space:]]+):.*/new_target:/}' Makefile
内容的提问来源于stack exchange,提问作者Athylus
相关产品推荐
相关产品推荐

