[for version 1.1.0]
buildpy2 generates files based on rules. Each rule has:
- A set of files that it is capable of creating
- A set of prerequisite files that are required in order to create a given file
- A function to create ('build') the file in question
- A 'phony' flag, which tells the system to always run the build function regardless of the state of the file or its prerequisites.
To build a given input file, the build system searches for the first rule that can build that file. Unlike Make, the system only considers the first rule that it finds. This may change in the future.
If no rule is found to build the file, the system only checks if the file already exists. If the file does not exist, the build exits with an error.
However, if a rule is found, the system checks all of the prerequisites that the rule provides for the file and attempts to build them. Then it decides whether to build the target file:
- If the rule is marked as 'phony', it is always rebuilt.
- If any of the prerequisites were rebuilt, the target file is also rebuilt.
- If the target file does not exist, it is rebuilt.
- If any of the prerequisites exist and have a newer modification time than the target file, it is rebuilt.
Rules are defined as subclasses of the Rule class. Subclasses should
implement the following functions:
__init__: 'Phony' rules should callsuper().__init__with thephonyargument set toTrue.can_build(self, file): This should returnTrueif this rule can build the given input file regardless of its prerequisites.get_prereqs(self, file): Takes an input file previously validated bycan_buildand returns a list of prerequisite files needed for that file.build(self, file): This should run the build function for the given input file, which has previously been validated bycan_build. Prerequisites for the file should exist at this point.
Since rules can be fairly bulky and complex, some built-in rules have been defined for convenience:
Target is a special type of rule that can only build a single specific
file. Its constructor takes several arguments:
file: The specific target fileprerequisites: A list of prerequisite files required to build the target filebuild_func: A function or lambda to build the input file. For convenience, the function is passed the input file and the list of prerequisites.
If the build function isNone, no action is taken to build the file.phony: [optional] Set toTrueto mark this target as 'phony'. This is useful if the target file is not actually a file, or for targets such as 'all', 'clean', 'install', etc.
Example: The all target
# 'all' target builds the library and documentation
rules.append(Target('all', ['libthing.so', 'doc'], None, True))This rule can be used to compile C and C++ files. It manages dependency files and file paths. Its constructor takes several arguments:
build_dir: where to put build files. It is not recommended to set this to'.'or the current working directory.compiler: the path to the compiler executable.options: Compiler options in a listsrc_ext: [optional] Set the source file extension (.cppby default)out_ext: [optional] Set the output file extension (.oby default)
CppRule will build any files with the extension {src_ext}.{out_ext} that
exist in {build_dir}. It reads prerequisites from the compiler-generated
dependency file, which is generated using the -MMD compiler option.
To convert a source file into an output file, a convenience function
CppRule.gen_buildfile() is provided. This function takes the source file
and build directory as parameters, and it returns a build file.
Example: Converting source files to object files
sources = ['src/a.cpp', 'src/b.cpp', 'src/main.cpp']
objs = [CppRule.gen_buildfile(f) for f in sources]Example: Creating rules for C and C++ files
# convert .cpp -> .cpp.o
rules.append(CppRule('build/', '/usr/bin/g++', cxx_opts, '.cpp', '.o'))
# convert .c -> .c.o
rules.append(CppRule('build/', '/usr/bin/gcc', c_opts, '.c', '.o'))This rule will compile an ELF file (shared library or executable) from several object files and/or libraries. Its constructor takes the following parameters:
file: The output file to buildobjs: A list of object files to linklibs: A list of (shared or static) library files to link. These library files must be namedlib{name}.aorlib{name}.so.compiler: Path to the compileroptions: Link options
This rule builds a static library file from several object files. Its constructor takes the following parameters:
file: The output.afile to buildobjs: A list of object files to archivearchiver: Path to the compiler toolchain'sarprogram
The build system provides functions to build rules, run external code, and check files.
run_build(rules, def_target): Build the file specified on the command line, or the target specified bydef_targetif nothing is given on the command line.build(rules, rule, file): Build a file with the given rule.run(args, pwd='.'): Run an external program, blocking until it finishes. If the program returns a non-zero exit code, this function will forcibly quit the Python process.exists(f): Shorthand foros.path.exists(f)is_newer(f1, f2): ReturnsTrueifff1was modified more recently thanf2.