关于make命令与build.sh脚本核心差异及make自动判定的技术问询
Great questions—these are common points of confusion when moving from simple shell scripts to proper build tools like make. Let’s break this down step by step.
1. Main Differences Between make and Running build.sh Directly
Incremental vs. Full Builds
makeis built around dependency tracking: it only rebuilds parts of your project that have changed. If you modify a single source file,makewill recompile just that file and any targets that depend on it. Abuild.shscript, by contrast, usually runs all its commands from start to finish every time you execute it—even if 99% of your files are unchanged. This can waste a lot of time on large projects.Structured Rule Definitions vs. Linear Script Logic
makeuses a Makefile to define explicit rules (targets, dependencies, and build commands). These rules are modular, reusable, and easy to update as your project grows. Abuild.shis a linear shell script; as your project gets more complex, the script can become bloated with nested conditionals and duplicated commands, making it harder to maintain.Built-in Target Flexibility
makesupports multiple targets out of the box. You can define targets likemake clean(to delete build artifacts),make install(to copy binaries to system directories), ormake test(to run tests) with minimal effort. For abuild.shto do the same, you’d have to manually add command-line argument handling (like./build.sh clean) and write all the associated logic yourself.
2. What Does "Automatic Determination" Mean in make?
Linux手册中定义make为:一款用于从源代码构建和维护多组程序(及其他类型文件)的工具,其用途是自动判定大型程序中哪些部分需要重新编译,并执行必要的重新编译命令。
This "automatic determination" refers to make’s ability to track file modification times (mtime) and compare them between targets and their dependencies:
- For each rule in your Makefile (e.g.,
main: main.c utils.c),makechecks if the target file (main) exists. If not, it runs the build command to create it. - If the target exists,
makecompares the modification time of the target against all its dependencies (main.c,utils.c). If any dependency has a newer mtime than the target,makeknows the dependency has been changed, so it re-runs the build command to update the target. - If all dependencies are older than the target,
makeskips the rule entirely, outputting something likemake: 'main' is up to date.
This is the core superpower of make—it eliminates unnecessary work by only rebuilding what’s actually changed.
Core Difference Between make and build.sh (Revisited)
The biggest gap is native dependency tracking and incremental build support. make is purpose-built for this task, with decades of optimization for handling complex project dependencies. A build.sh can replicate this behavior, but only if you manually write code to check file mtimes, track dependencies, and skip unchanged targets—something that’s error-prone and tedious for large projects.
Additionally, make comes with built-in variables (like CC for the compiler, CFLAGS for compile flags) and implicit rules (e.g., it knows how to compile .c files to .o files without you writing the full command), which simplify build configuration. build.sh gives you full shell flexibility but requires you to define every single command from scratch.
内容的提问来源于stack exchange,提问作者Rudziankoŭ

