Fix building the Dub frontend package on Windows

The Dub package was unconditionally running the `config.sh` shell
script to generate the `VERSION` file. A Bash shell script will not
work on Windows. Therefore the `config.sh` script has been ported to
D, which will work on both Windows and Posix.
This commit is contained in:
Jacob Carlborg 2018-10-28 12:26:40 +01:00
parent 927de2e31a
commit 71e2660171
4 changed files with 96 additions and 21 deletions

77
config.d Normal file
View file

@ -0,0 +1,77 @@
/**
Generates the compiler version, the version printed with `dmd --version`.
Outputs a file with the generated version which is imported as a string literal
in the compiler source code.
*/
module config;
void main(const string[] args)
{
import std.file : mkdirRecurse, readText;
import std.path : buildPath;
const outputDirectory = args[1];
const versionFile = args[2];
version (Posix)
const sysConfigDirectory = args[3];
mkdirRecurse(outputDirectory);
const version_ = generateVersion(versionFile);
updateIfChanged(buildPath(outputDirectory, "VERSION"), version_);
version (Posix)
{
const path = buildPath(outputDirectory, "SYSCONFDIR.imp");
updateIfChanged(path, sysConfigDirectory);
}
}
/**
Generates the version for the compiler.
If anything goes wrong in the process the contents of the file
`versionFile` will be returned.
Params:
versionFile = a file containing a version, used for backup if generating the
version fails
Returns: the generated version, or the content of `versionFile`
*/
string generateVersion(const string versionFile)
{
import std.process : execute;
import std.file : readText;
import std.string : strip;
const result = execute(["git", "describe", "--dirty"]);
return result.status == 0 ? result.output.strip : versionFile.readText;
}
/**
Writes given the content to the given file.
The content will only be written to the file specified in `path` if that file
doesn't exist, or the content of the existing file is different from the given
content.
This makes sure the timestamp of the file is only updated when the
content has changed. This will avoid rebuilding when the content hasn't changed.
Params:
path = the path to the file to write the content to
content = the content to write to the file
*/
void updateIfChanged(const string path, const string content)
{
import std.file : exists, readText, write;
const existingContent = path.exists ? path.readText : "";
if (content != existingContent)
write(path, content);
}

View file

@ -1,17 +0,0 @@
#!/bin/sh
set -ue
OUTDIR="$1"
VERSIONFILE="$2"
SYSCONFDIR="$3"
VERSION=$(git describe --dirty 2>/dev/null || cat "$VERSIONFILE") # prefer git describe
mkdir -p "$OUTDIR"
# only update config files when they actually differ to avoid unnecessary rebuilds
if [ "$VERSION" != "$(cat "$OUTDIR/VERSION" 2>/dev/null)" ]; then
printf "$VERSION" > "$OUTDIR/VERSION"
fi
if [ "$SYSCONFDIR" != "$(cat "$OUTDIR/SYSCONFDIR.imp" 2>/dev/null)" ]; then
printf "$SYSCONFDIR" > "$OUTDIR/SYSCONFDIR.imp"
fi

View file

@ -29,7 +29,8 @@ subPackage {
"src/dmd/tokens.d" \
"src/dmd/utf.d"
preGenerateCommands `cd "$${DUB_PACKAGE_DIR}" && ./config.sh generated/dub VERSION /etc`
preGenerateCommands `"$${DC}" -run "$${DUB_PACKAGE_DIR}/config.d" "$${DUB_PACKAGE_DIR}/generated/dub" "$${DUB_PACKAGE_DIR}/VERSION" /etc` platform="posix"
preGenerateCommands `"%DC%" -run "%DUB_PACKAGE_DIR%/config.d" "%DUB_PACKAGE_DIR%/generated/dub" "%DUB_PACKAGE_DIR%/VERSION"` platform="windows"
stringImportPaths "generated/dub"
dependency "dmd:root" version="*"
@ -53,7 +54,8 @@ subPackage {
subPackage {
name "frontend"
targetType "library"
preGenerateCommands `cd "$${DUB_PACKAGE_DIR}" && ./config.sh generated/dub VERSION /etc`
preGenerateCommands `"$${DC}" -run "$${DUB_PACKAGE_DIR}/config.d" "$${DUB_PACKAGE_DIR}/generated/dub" "$${DUB_PACKAGE_DIR}/VERSION" /etc` platform="posix"
preGenerateCommands `"%DC%" -run "%DUB_PACKAGE_DIR%/config.d" "%DUB_PACKAGE_DIR%/generated/dub" "%DUB_PACKAGE_DIR%/VERSION"` platform="windows"
stringImportPaths "generated/dub"
stringImportPaths "res"
versions "NoBackend"

View file

@ -461,7 +461,7 @@ toolchain-info:
$G/backend.a: $(G_OBJS) $(G_DOBJS) $(SRC_MAKE)
$(AR) rcs $@ $(G_OBJS) $(G_DOBJS)
$G/lexer.a: $(LEXER_SRCS) $(LEXER_ROOT) $(HOST_DMD_PATH) $(SRC_MAKE)
$G/lexer.a: $(LEXER_SRCS) $(LEXER_ROOT) $(HOST_DMD_PATH) $(SRC_MAKE) $(STRING_IMPORT_FILES)
CC="$(HOST_CXX)" $(HOST_DMD_RUN) -lib -of$@ $(MODEL_FLAG) -J$G -L-lstdc++ $(DFLAGS) $(LEXER_SRCS) $(LEXER_ROOT)
$G/dmd_frontend: $(FRONT_SRCS) $D/gluelayer.d $(ROOT_SRCS) $G/newdelete.o $G/lexer.a $(STRING_IMPORT_FILES) $(HOST_DMD_PATH)
@ -544,8 +544,21 @@ $(optabgen_files): optabgen.out
optabgen.out : $G/optabgen
######## VERSION
########################################################################
# The version file should be updated on every build
# However, the version check script only touches the VERSION file if it
# actually has changed.
$(shell ../config.sh "$G" ../VERSION $(SYSCONFDIR))
$G/version_check: ../config.d $(HOST_DMD_PATH)
@echo " (HOST_DMD_RUN) $< $<"
$(HOST_DMD_RUN) $< -of$@
$G/VERSION: $G/version_check ../VERSION FORCE
@$< $G ../VERSION $(SYSCONFDIR)
$G/SYSCONFDIR.imp: $G/VERSION
FORCE: ;
# Generic rules for all source files
########################################################################