You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2026-10-23 21:28:56 +03:00
The harness had a file per version that did nothing but expand a macro for it, a block of declarations for the functions those files defined, and the struct that dispatched to them, all maintained by hand, so adding a PostgreSQL version meant adding a file and three more entries to keep in step. The interfaces the binary uses are generated from the same versions, so the harness generates its own the same way with 'build.py postgres-harness'. What differs between the two interfaces is a declaration: the header the macros are read from, how the generated code includes it, the prefix of the functions the macros define, and where the interface is rendered. The versions, the vendored types that are renamed for each of them, and the defines that are undefined after each one are the same, so one generator renders both. The harness interface is one translation unit with the vendored header included again for each version, the way the binary's is, rather than a translation unit per version. The functions are static, so the declarations and the pragma that silenced the missing prototypes go away with the files, and they are named for the version the way the binary's are, e.g. 19 rather than 190. The harness macros are renamed to say which function each one defines, since the generator names a function after the macro that defines it, and the macro that expanded all of them for a version is gone because the generated file expands each one itself. The header they are declared in loses its include guard and everything that does not vary by version, since it is now included once per version and the module that expands the macros includes the rest. The system id constants are generated into the harness header rather than into a file of their own, so the header still holds everything the harness declares. The defines are replaced where they are, which is what the version in src/version.h is already generated by. Every version gets the offset form that only two of them had, since a block that reads the same for every version is easier to follow than one that does not. The interface is generated rather than committed, the same as the interface the binary uses, so a test run generates it and the repository copy duplicates it for a unit build to compile.
125 lines
5.4 KiB
Python
125 lines
5.4 KiB
Python
"""Build Command.
|
|
|
|
Parses the command line and runs the requested generator. Each generator reads a declaration from the repository and writes the C it
|
|
describes into the build path, which is the repository itself for the files that are committed and the build directory for the files
|
|
meson generates as it builds.
|
|
|
|
The documentation generates its own option parse tables and help from its own declarations, so it runs these same generators with
|
|
the repository set to the documentation directory."""
|
|
|
|
####################################################################################################################################
|
|
import argparse
|
|
import os
|
|
|
|
from config.parse import bld_cfg_parse
|
|
from config.render import bld_cfg_render
|
|
from error.parse import bld_err_parse
|
|
from error.render import bld_err_render
|
|
from help.parse import bld_hlp_parse
|
|
from help.render import bld_hlp_render
|
|
|
|
# The help declaration, which lives with the documentation because that is what most of it is for
|
|
_PATH_HELP = "doc/xml/reference.xml"
|
|
from postgres.parse import BLD_PG_INTERFACE_HARNESS, bld_pg_parse
|
|
from postgres.render import bld_pg_render, bld_pg_system_id_render, bld_pg_version_render
|
|
|
|
|
|
####################################################################################################################################
|
|
def _path_help(config):
|
|
"""Path of the help declaration."""
|
|
|
|
return os.path.join(config.repo_path, _PATH_HELP)
|
|
|
|
|
|
####################################################################################################################################
|
|
def _build_config(config):
|
|
"""Generate the command and option configuration."""
|
|
|
|
bld_cfg_render(config.build_path, bld_cfg_parse(config.repo_path), True)
|
|
|
|
|
|
####################################################################################################################################
|
|
def _build_error(config):
|
|
"""Generate the error types."""
|
|
|
|
bld_err_render(config.build_path, bld_err_parse(config.repo_path))
|
|
|
|
|
|
####################################################################################################################################
|
|
def _build_help(config):
|
|
"""Generate the help the binary carries for itself."""
|
|
|
|
bld_cfg = bld_cfg_parse(config.repo_path)
|
|
|
|
bld_hlp_render(config.build_path, bld_cfg, bld_hlp_parse(_path_help(config), bld_cfg, False))
|
|
|
|
|
|
####################################################################################################################################
|
|
def _build_postgres(config):
|
|
"""Generate the PostgreSQL interfaces."""
|
|
|
|
bld_pg_render(config.build_path, bld_pg_parse(config.repo_path))
|
|
|
|
|
|
####################################################################################################################################
|
|
def _build_postgres_harness(config):
|
|
"""Generate the PostgreSQL interfaces the test harness writes pg_control and WAL with."""
|
|
|
|
bld_pg = bld_pg_parse(config.repo_path, BLD_PG_INTERFACE_HARNESS)
|
|
|
|
bld_pg_render(config.build_path, bld_pg)
|
|
|
|
# The system ids are generated into a header that is hand-written apart from them, so they go to the repository rather than to
|
|
# wherever the generated code is going
|
|
bld_pg_system_id_render(config.repo_path, bld_pg)
|
|
|
|
|
|
####################################################################################################################################
|
|
def _build_postgres_version(config):
|
|
"""Generate the PostgreSQL version constants."""
|
|
|
|
bld_pg_version_render(config.build_path, bld_pg_parse(config.repo_path))
|
|
|
|
|
|
####################################################################################################################################
|
|
# Generators, in the order they are listed in the help
|
|
_COMMAND_LIST = {
|
|
"config": _build_config,
|
|
"error": _build_error,
|
|
"help": _build_help,
|
|
"postgres": _build_postgres,
|
|
"postgres-harness": _build_postgres_harness,
|
|
"postgres-version": _build_postgres_version,
|
|
}
|
|
|
|
|
|
####################################################################################################################################
|
|
def cfg_load(arg_list, path_repo):
|
|
"""Parse the command line."""
|
|
|
|
parser = argparse.ArgumentParser(prog="build.py", description="Generate code for pgBackRest.")
|
|
parser.add_argument("command", choices=_COMMAND_LIST, metavar="COMMAND", help="what to generate: %s" % ", ".join(_COMMAND_LIST))
|
|
parser.add_argument("--repo-path", default=path_repo, metavar="PATH", help="path the declarations are read from")
|
|
parser.add_argument("--build-path", metavar="PATH", help="path the generated code is written to, defaults to the repository")
|
|
|
|
result = parser.parse_args(arg_list)
|
|
|
|
# A relative path is made absolute so it does not depend on where the tool was run from, which meson does not promise
|
|
result.repo_path = os.path.abspath(result.repo_path)
|
|
|
|
# The generated code goes into the repository unless the caller sends it somewhere else, which meson does for the files it
|
|
# generates as it builds rather than the files that are committed
|
|
if result.build_path is None:
|
|
result.build_path = result.repo_path
|
|
else:
|
|
result.build_path = os.path.abspath(result.build_path)
|
|
|
|
return result
|
|
|
|
|
|
####################################################################################################################################
|
|
def cmd_build(config):
|
|
"""Run the requested generator."""
|
|
|
|
_COMMAND_LIST[config.command](config)
|