mirror of
https://github.com/neondatabase/neon.git
synced 2025-12-22 21:59:59 +00:00
Use custom install command in Makefile to speed up incremental builds (#2458)
Fixes #1873: previously any run of `make` caused the `postgres-v15-headers` target to build. It copied a bunch of headers via `install -C`. Unfortunately, some origins were symlinks in the `./pg_install/build` directory pointing inside `./vendor/postgres-v15` (e.g. `pg_config_os.h` pointing to `linux.h`). GNU coreutils' `install` ignores the `-C` key for non-regular files and always overwrites the destination if the origin is a symlink. That in turn made Cargo rebuild the `postgres_ffi` crate and all its dependencies because it thinks that Postgres headers changed, even if they did not. That was slow. Now we use a custom script that wraps the `install` program. It handles one specific case and makes sure individual headers are never copied if their content did not change. Hence, `postgres_ffi` is not rebuilt unless there were some changes to the C code. One may still have slow incremental single-threaded builds because Postgres Makefiles spawn about 2800 sub-makes even if no files have been changed. A no-op build takes "only" 3-4 seconds on my machine now when run with `-j30`, and 20 seconds when run with `-j1`.
This commit is contained in:
2
Makefile
2
Makefile
@@ -38,7 +38,7 @@ endif
|
||||
# headers, the mtime of the headers are not changed when there have
|
||||
# been no changes to the files. Changing the mtime triggers an
|
||||
# unnecessary rebuild of 'postgres_ffi'.
|
||||
PG_CONFIGURE_OPTS += INSTALL='install -C'
|
||||
PG_CONFIGURE_OPTS += INSTALL='$(ROOT_PROJECT_DIR)/scripts/ninstall.sh -C'
|
||||
|
||||
# Choose whether we should be silent or verbose
|
||||
CARGO_BUILD_FLAGS += --$(if $(filter s,$(MAKEFLAGS)),quiet,verbose)
|
||||
|
||||
24
scripts/ninstall.sh
Executable file
24
scripts/ninstall.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
# GNU coreutil's `install -C` always overrides the destination if the source
|
||||
# is not a regular file, which is the case with lots of headers symlinked into
|
||||
# the build directory by `./configure`. That causes Rust's Cargo to think that
|
||||
# Postgres headers have been updated after `make` call even if no files have been
|
||||
# touched. That causes long recompilation of `postgres_ffi` and all dependent
|
||||
# packages. To counter that, we handle a special case here: do not copy the file
|
||||
# if its content did not change. We only handle a single case where `install`
|
||||
# installs a single file with a specific set of arguments, the rest does not
|
||||
# matter in our configuration.
|
||||
#
|
||||
# Such behavior may be incorrect if e.g. permissions have changed, but it should
|
||||
# not happen during normal Neon development that often, and rebuild should help.
|
||||
#
|
||||
# See https://github.com/neondatabase/neon/issues/1873
|
||||
if [ "$#" == "5" ]; then
|
||||
if [ "$1" == "-C" ] && [ "$2" == "-m" ] && [ "$3" == "644" ]; then
|
||||
if [ -e "$5" ] && diff -q "$4" "$5" >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
install "$@"
|
||||
Reference in New Issue
Block a user