Build system: redo how version number tracking works

* Remove the "version suffix" and BUILD_INFO.txt mechanisms, which I
   believe no one uses except winpty itself.  Instead, a suffix can be
   added in the VERSION.txt file.

 * Instead of passing the version and commit info as a preprocessor macro
   when building every C++ file, write the info into a GenVersion.h
   header that is only included by WinptyVersion.cc.

 * Instead of writing a BUILD_INFO.txt in ship.py, pass COMMIT_HASH=<hash>
   to make.

These changes accomplish two things:

 * People who build a tag from source won't see a "<ver>-dev" suffix
   anymore.

 * Changing the version or the commit will correctly rebuild the version
   object files (and only those object files).  It will also relink every
   binary.

Fixes https://github.com/rprichard/winpty/issues/72
This commit is contained in:
Ryan Prichard 2017-01-17 23:39:14 -06:00
parent 643e14894a
commit 67a34b6c03
15 changed files with 83 additions and 85 deletions

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ winpty.opensdf
/ship/packages /ship/packages
/src/Default /src/Default
/src/Release /src/Release
/src/gen

View File

@ -45,15 +45,12 @@ ifeq "$(wildcard config.mk)" ""
endif endif
include config.mk include config.mk
VERSION_TXT_CONTENT := $(shell cat VERSION.txt | tr -d '\r\n')
COMMON_CXXFLAGS += \ COMMON_CXXFLAGS += \
-DWINPTY_VERSION=$(VERSION_TXT_CONTENT) \
-DWINPTY_VERSION_SUFFIX=$(VERSION_SUFFIX) \
-DWINPTY_COMMIT_HASH=$(COMMIT_HASH) \
-MMD -Wall \ -MMD -Wall \
-DUNICODE \ -DUNICODE \
-D_UNICODE \ -D_UNICODE \
-D_WIN32_WINNT=0x0501 -D_WIN32_WINNT=0x0501 \
-Ibuild/gen
UNIX_CXXFLAGS += \ UNIX_CXXFLAGS += \
$(COMMON_CXXFLAGS) $(COMMON_CXXFLAGS)
@ -73,6 +70,11 @@ else
PCH_DEP := PCH_DEP :=
endif endif
build/gen/GenVersion.h : VERSION.txt $(COMMIT_HASH_DEP) | $$(@D)/.mkdir
$(info Updating build/gen/GenVersion.h)
@echo "const char GenVersion_Version[] = \"$(shell cat VERSION.txt | tr -d '\r\n')\";" > build/gen/GenVersion.h
@echo "const char GenVersion_Commit[] = \"$(COMMIT_HASH)\";" >> build/gen/GenVersion.h
build/mingw/PrecompiledHeader.h : src/shared/PrecompiledHeader.h | $$(@D)/.mkdir build/mingw/PrecompiledHeader.h : src/shared/PrecompiledHeader.h | $$(@D)/.mkdir
$(info Copying $< to $@) $(info Copying $< to $@)
@cp $< $@ @cp $< $@
@ -84,13 +86,13 @@ build/mingw/PrecompiledHeader.h.gch : build/mingw/PrecompiledHeader.h | $$(@D)/.
-include build/mingw/PrecompiledHeader.h.d -include build/mingw/PrecompiledHeader.h.d
define def_unix_target define def_unix_target
build/$1/%.o : src/%.cc VERSION.txt | $$$$(@D)/.mkdir build/$1/%.o : src/%.cc | $$$$(@D)/.mkdir
$$(info Compiling $$<) $$(info Compiling $$<)
@$$(UNIX_CXX) $$(UNIX_CXXFLAGS) $2 -I src/include -c -o $$@ $$< @$$(UNIX_CXX) $$(UNIX_CXXFLAGS) $2 -I src/include -c -o $$@ $$<
endef endef
define def_mingw_target define def_mingw_target
build/$1/%.o : src/%.cc VERSION.txt $$(PCH_DEP) | $$$$(@D)/.mkdir build/$1/%.o : src/%.cc $$(PCH_DEP) | $$$$(@D)/.mkdir
$$(info Compiling $$<) $$(info Compiling $$<)
@$$(MINGW_CXX) $$(MINGW_CXXFLAGS) $2 -I src/include -c -o $$@ $$< @$$(MINGW_CXX) $$(MINGW_CXXFLAGS) $2 -I src/include -c -o $$@ $$<
endef endef
@ -147,7 +149,7 @@ clean :
.PHONY : clean-msvc .PHONY : clean-msvc
clean-msvc : clean-msvc :
rm -fr src/Default src/Release src/.vs rm -fr src/Default src/Release src/.vs src/gen
rm -f src/*.vcxproj src/*.vcxproj.filters src/*.sln src/*.sdf rm -f src/*.vcxproj src/*.vcxproj.filters src/*.sln src/*.sdf
.PHONY : distclean .PHONY : distclean

View File

@ -1 +1 @@
0.4.2 0.4.2-dev

22
configure vendored
View File

@ -156,22 +156,12 @@ if test $IS_MSYS1 = 1; then
echo MINGW_ENABLE_CXX11_FLAG := -std=gnu++11 >> config.mk echo MINGW_ENABLE_CXX11_FLAG := -std=gnu++11 >> config.mk
fi fi
# Figure out how to embed build info (e.g. git commit) into the binary. if test -d .git -a -f .git/HEAD -a -f .git/index && git rev-parse HEAD >&/dev/null; then
if test -f BUILD_INFO.txt; then echo "Commit info: git"
echo "Build info: source package" echo 'COMMIT_HASH = $(shell git rev-parse HEAD)' >> config.mk
eval $(grep '^VERSION_SUFFIX=' BUILD_INFO.txt | tr -d '\r') echo 'COMMIT_HASH_DEP := config.mk .git/HEAD .git/index' >> config.mk
eval $(grep '^COMMIT_HASH=' BUILD_INFO.txt | tr -d '\r')
echo "VERSION_SUFFIX := ${VERSION_SUFFIX}" >> config.mk
echo "COMMIT_HASH := ${COMMIT_HASH}" >> config.mk
echo "BUILD_INFO_DEP := config.mk" >> config.mk
elif test -d .git && git rev-parse HEAD >&/dev/null; then
echo "Build info: git"
echo 'VERSION_SUFFIX := -dev' >> config.mk
echo 'COMMIT_HASH := $(shell git rev-parse HEAD)' >> config.mk
echo 'BUILD_INFO_DEP := config.mk .git/HEAD' >> config.mk
else else
echo "Build info: none" echo "Commit info: none"
echo 'VERSION_SUFFIX := -dev' >> config.mk
echo 'COMMIT_HASH := none' >> config.mk echo 'COMMIT_HASH := none' >> config.mk
echo 'BUILD_INFO_DEP := config.mk' >> config.mk echo 'COMMIT_HASH_DEP := config.mk' >> config.mk
fi fi

View File

@ -16,11 +16,6 @@ topDir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
with open(topDir + "/VERSION.txt", "rt") as f: with open(topDir + "/VERSION.txt", "rt") as f:
winptyVersion = f.read().strip() winptyVersion = f.read().strip()
def writeBuildInfo():
with open(topDir + "/BUILD_INFO.txt", "w") as f:
f.write("VERSION_SUFFIX=__none__\n")
f.write("COMMIT_HASH=" + commitHash + "\n")
def rmrf(patterns): def rmrf(patterns):
for pattern in patterns: for pattern in patterns:
for path in glob.glob(pattern): for path in glob.glob(pattern):

View File

@ -88,7 +88,7 @@ def checkoutGyp():
def cleanMsvc(): def cleanMsvc():
common_ship.rmrf(""" common_ship.rmrf("""
src/Release src/.vs src/Release src/.vs src/gen
src/*.vcxproj src/*.vcxproj.filters src/*.sln src/*.sdf src/*.vcxproj src/*.vcxproj.filters src/*.sln src/*.sdf
""".split()) """.split())
@ -106,7 +106,6 @@ def build(arch, packageDir, xp=False):
'"' + devCmdPath + '" && ' '"' + devCmdPath + '" && '
" vcbuild.bat" + " vcbuild.bat" +
" --gyp-msvs-version " + versionInfo["gyp_version"] + " --gyp-msvs-version " + versionInfo["gyp_version"] +
" --version-suffix __none__" +
" --msvc-platform " + archInfo["msvc_platform"] " --msvc-platform " + archInfo["msvc_platform"]
) )

View File

@ -77,13 +77,17 @@ def buildTarget(target):
oldPath = os.environ["PATH"] oldPath = os.environ["PATH"]
os.environ["PATH"] = target["path"] + ";" + common_ship.defaultPathEnviron os.environ["PATH"] = target["path"] + ";" + common_ship.defaultPathEnviron
subprocess.check_call(["sh.exe", "configure"]) subprocess.check_call(["sh.exe", "configure"])
subprocess.check_call(["make.exe", "clean"])
makeBinary = target.get("make_binary", "make.exe") makeBinary = target.get("make_binary", "make.exe")
buildArgs = [makeBinary, "USE_PCH=0", "all", "tests"] subprocess.check_call([makeBinary, "clean"])
buildArgs += ["-j%d" % multiprocessing.cpu_count()] makeBaseCmd = [
subprocess.check_call(buildArgs) makeBinary,
"USE_PCH=0",
"COMMIT_HASH=" + common_ship.commitHash,
"PREFIX=ship/packages/" + packageName
]
subprocess.check_call(makeBaseCmd + ["all", "tests", "-j%d" % multiprocessing.cpu_count()])
subprocess.check_call(["build\\trivial_test.exe"]) subprocess.check_call(["build\\trivial_test.exe"])
subprocess.check_call([makeBinary, "USE_PCH=0", "PREFIX=ship/packages/" + packageName, "install"]) subprocess.check_call(makeBaseCmd + ["install"])
subprocess.check_call(["tar.exe", "cvfz", subprocess.check_call(["tar.exe", "cvfz",
packageName + ".tar.gz", packageName + ".tar.gz",
packageName], cwd=os.path.join(os.getcwd(), "ship", "packages")) packageName], cwd=os.path.join(os.getcwd(), "ship", "packages"))
@ -91,19 +95,15 @@ def buildTarget(target):
os.environ["PATH"] = oldPath os.environ["PATH"] = oldPath
def main(): def main():
try: if os.path.exists("ship\\packages"):
common_ship.writeBuildInfo() shutil.rmtree("ship\\packages")
if os.path.exists("ship\\packages"): oldPath = os.environ["PATH"]
shutil.rmtree("ship\\packages") for t in BUILD_TARGETS:
oldPath = os.environ["PATH"] os.environ["PATH"] = t["path"] + ";" + common_ship.defaultPathEnviron
for t in BUILD_TARGETS: subprocess.check_output(["tar.exe", "--help"])
os.environ["PATH"] = t["path"] + ";" + common_ship.defaultPathEnviron subprocess.check_output(["make.exe", "--help"])
subprocess.check_output(["tar.exe", "--help"]) for t in BUILD_TARGETS:
subprocess.check_output(["make.exe", "--help"]) buildTarget(t)
for t in BUILD_TARGETS:
buildTarget(t)
finally:
os.remove("BUILD_INFO.txt")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -52,6 +52,8 @@ AGENT_OBJECTS = \
build/agent/shared/WinptyException.o \ build/agent/shared/WinptyException.o \
build/agent/shared/WinptyVersion.o build/agent/shared/WinptyVersion.o
build/agent/shared/WinptyVersion.o : build/gen/GenVersion.h
build/winpty-agent.exe : $(AGENT_OBJECTS) build/winpty-agent.exe : $(AGENT_OBJECTS)
$(info Linking $@) $(info Linking $@)
@$(MINGW_CXX) $(MINGW_LDFLAGS) -o $@ $^ @$(MINGW_CXX) $(MINGW_LDFLAGS) -o $@ $^

View File

@ -32,6 +32,8 @@ DEBUGSERVER_OBJECTS = \
build/debugserver/shared/WinptyAssert.o \ build/debugserver/shared/WinptyAssert.o \
build/debugserver/shared/WinptyException.o build/debugserver/shared/WinptyException.o
build/debugserver/shared/WindowsVersion.o : build/gen/GenVersion.h
build/winpty-debugserver.exe : $(DEBUGSERVER_OBJECTS) build/winpty-debugserver.exe : $(DEBUGSERVER_OBJECTS)
$(info Linking $@) $(info Linking $@)
@$(MINGW_CXX) $(MINGW_LDFLAGS) -o $@ $^ @$(MINGW_CXX) $(MINGW_LDFLAGS) -o $@ $^

View File

@ -37,6 +37,8 @@ LIBWINPTY_OBJECTS = \
build/libwinpty/shared/WinptyException.o \ build/libwinpty/shared/WinptyException.o \
build/libwinpty/shared/WinptyVersion.o build/libwinpty/shared/WinptyVersion.o
build/libwinpty/shared/WinptyVersion.o : build/gen/GenVersion.h
build/winpty.dll : $(LIBWINPTY_OBJECTS) build/winpty.dll : $(LIBWINPTY_OBJECTS)
$(info Linking $@) $(info Linking $@)
@$(MINGW_CXX) $(MINGW_LDFLAGS) -shared -o $@ $^ -Wl,--out-implib,build/winpty.lib @$(MINGW_CXX) $(MINGW_LDFLAGS) -shared -o $@ $^ -Wl,--out-implib,build/winpty.lib

24
src/shared/UpdateGenVersion.bat Executable file
View File

@ -0,0 +1,24 @@
@echo off
rem -- Echo the git commit hash. If git isn't available for some reason,
rem -- output nothing instead.
mkdir ..\gen 2>nul
set /p VERSION=<..\..\VERSION.txt
git rev-parse HEAD >nul 2>nul && (
for /F "delims=" %%i IN ('git rev-parse HEAD') DO set COMMIT=%%i
) || (
set COMMIT=none
)
echo // AUTO-GENERATED BY %0>..\gen\GenVersion.h
echo const char GenVersion_Version[] = "%VERSION%";>>..\gen\GenVersion.h
echo const char GenVersion_Commit[] = "%COMMIT%";>>..\gen\GenVersion.h
rem -- The winpty.gyp file expects the script to output the include directory,
rem -- relative to src.
echo gen
rem -- Set ERRORLEVEL to 0 using this cryptic syntax.
(call )

View File

@ -25,25 +25,18 @@
#include "DebugClient.h" #include "DebugClient.h"
#define XSTRINGIFY(x) #x // This header is auto-generated by either the Makefile (Unix) or
#define STRINGIFY(x) XSTRINGIFY(x) // UpdateGenVersion.bat (gyp). It is placed in a 'gen' directory, which is
// added to the search path.
static const char *versionSuffix() { #include "GenVersion.h"
const char *ret = STRINGIFY(WINPTY_VERSION_SUFFIX);
if (!strcmp(ret, "__none__")) {
return "";
}
return ret;
}
void dumpVersionToStdout() { void dumpVersionToStdout() {
printf("winpty version %s%s\n", STRINGIFY(WINPTY_VERSION), versionSuffix()); printf("winpty version %s\n", GenVersion_Version);
printf("commit %s\n", STRINGIFY(WINPTY_COMMIT_HASH)); printf("commit %s\n", GenVersion_Commit);
} }
void dumpVersionToTrace() { void dumpVersionToTrace() {
trace("winpty version %s%s (commit %s)", trace("winpty version %s (commit %s)",
STRINGIFY(WINPTY_VERSION), GenVersion_Version,
versionSuffix(), GenVersion_Commit);
STRINGIFY(WINPTY_COMMIT_HASH));
} }

View File

@ -32,6 +32,8 @@ UNIX_ADAPTER_OBJECTS = \
build/unix-adapter/shared/WinptyAssert.o \ build/unix-adapter/shared/WinptyAssert.o \
build/unix-adapter/shared/WinptyVersion.o build/unix-adapter/shared/WinptyVersion.o
build/unix-adapter/shared/WinptyVersion.o : build/gen/GenVersion.h
build/$(UNIX_ADAPTER_EXE) : $(UNIX_ADAPTER_OBJECTS) build/winpty.dll build/$(UNIX_ADAPTER_EXE) : $(UNIX_ADAPTER_OBJECTS) build/winpty.dll
$(info Linking $@) $(info Linking $@)
@$(UNIX_CXX) $(UNIX_LDFLAGS) -o $@ $^ @$(UNIX_CXX) $(UNIX_LDFLAGS) -o $@ $^

View File

@ -1,8 +1,4 @@
{ {
# Pass -D VERSION_SUFFIX=<something> to gyp to override the suffix.
#
# The winpty.gyp file ignores the BUILD_INFO.txt file, if it exists.
#
# The MSVC generator is the default. Select the compiler version by # The MSVC generator is the default. Select the compiler version by
# passing -G msvs_version=<ver> to gyp. <ver> is a string like 2013e. # passing -G msvs_version=<ver> to gyp. <ver> is a string like 2013e.
# See gyp\pylib\gyp\MSVSVersion.py for sample version strings. You # See gyp\pylib\gyp\MSVSVersion.py for sample version strings. You
@ -13,18 +9,17 @@
# can be configured by passing variables to make, e.g.: # can be configured by passing variables to make, e.g.:
# make -j4 CXX=i686-w64-mingw32-g++ LDFLAGS="-static -static-libgcc -static-libstdc++" # make -j4 CXX=i686-w64-mingw32-g++ LDFLAGS="-static -static-libgcc -static-libstdc++"
'variables' : {
'VERSION_SUFFIX%' : '-dev',
},
'target_defaults' : { 'target_defaults' : {
'defines' : [ 'defines' : [
'UNICODE', 'UNICODE',
'_UNICODE', '_UNICODE',
'_WIN32_WINNT=0x0501', '_WIN32_WINNT=0x0501',
'NOMINMAX', 'NOMINMAX',
'WINPTY_VERSION=<!(cmd /c "cd .. && type VERSION.txt")', ],
'WINPTY_VERSION_SUFFIX=<(VERSION_SUFFIX)', 'include_dirs': [
'WINPTY_COMMIT_HASH=<!(cmd /c "cd shared && GetCommitHash.cmd")', # Add the 'src/gen' directory to the include path and force gyp to
# run the script (re)generating the version header.
'<!(cmd /c "cd shared && UpdateGenVersion.bat")',
], ],
}, },
'targets' : [ 'targets' : [

View File

@ -43,15 +43,6 @@ if "%1" == "--toolset" (
shift && shift shift && shift
goto :ParamLoop goto :ParamLoop
) )
if "%1" == "--version-suffix" (
if x%2 == x"" (
set GYP_ARGS=%GYP_ARGS% -D VERSION_SUFFIX=__none__
) else (
set GYP_ARGS=%GYP_ARGS% -D VERSION_SUFFIX=%2
)
shift && shift
goto :ParamLoop
)
echo error: Unrecognized argument: %1 echo error: Unrecognized argument: %1
exit /b 1 exit /b 1
:ParamDone :ParamDone