a942b13 dropped this as redundant with the header link, but readers who finish the guide below the table never see that header link and lose the pointer to Package Management entirely.
Co-Authored-By: Claude <noreply@anthropic.com>
3.4 KiB
Where Make would go, a Python build tool takes over, and SCons compiles C and C++. Invoke runs shell commands as tasks, and doit reruns only what changed.
How to choose:
- C, C++, or Fortran code compiled from source: SCons
- Shell commands run as named tasks with CLI flags: Invoke
- Tasks that rerun only when their input files change: doit
- Your own CLI program built from tasks: Invoke
SCons builds software from source code. Its site calls it an improved, cross-platform substitute for the classic Make utility, with dependency analysis for C, C++, and Fortran built in. Your build file is a Python script named SConstruct: put Program('hello.c') in it and run scons. You declare what to build, and SCons works out the build order, whatever order you call the builders in. For a source tree with subdirectories, split the build into SConscript files that the top-level SConstruct pulls in. SCons puts a correct build first: by default, it decides a file has changed from a hash of its contents, not its modification time.
Invoke turns your project's shell commands into Python tasks. Write them in a tasks.py as @task functions whose first argument is a context, and run commands with c.run(). Each parameter becomes a CLI flag, and invoke --list shows your tasks. A task can name pre-tasks to run first, like clean before build. When one flat list of tasks gets crowded, group them into namespaces with Collection.
Invoke can also power your own CLI program, with your tasks as its commands. It sticks to local commands and leaves servers and network commands to a separate library built on it.
doit runs only what changed. Tasks live in a dodo.py: each function whose name starts with task_ returns a dict, and its actions are shell commands or Python functions. List a task's file_dep and targets, and doit skips it when its dependencies haven't changed and its targets exist. Inputs don't have to be files: an uptodate check such as config_changed reruns a task when a config string or dict changes.
Looking for the tool that builds your package's wheels and publishes them to PyPI? That's packaging, covered in Package Management.