Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .circleci/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,14 @@ coverage()
if [ -f ~/dlang/install.sh ] ; then
source "$(CURL_USER_AGENT=\"$CURL_USER_AGENT\" bash ~/dlang/install.sh dmd-$HOST_DMD_VER --activate)"
fi
RDMD="$(type -p rdmd)"

# build dmd, druntime, and phobos
make -j$N -C src -f posix.mak MODEL=$MODEL HOST_DMD=$DMD BUILD=$BUILD ENABLE_WARNINGS=1 PIC="$PIC" all
if [ "$MODEL" == "64" ] ; then
"$RDMD" ./src/build.d MODEL=$MODEL HOST_DMD=$DMD BUILD=$BUILD ENABLE_WARNINGS=1 PIC="$PIC" all
else
make -j$N -C src -f posix.mak MODEL=$MODEL HOST_DMD=$DMD BUILD=$BUILD ENABLE_WARNINGS=1 PIC="$PIC" all
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: MODEL=32 doesn't fully work yet. I will fix this in another PR.

fi
make -j$N -C ../druntime -f posix.mak MODEL=$MODEL PIC="$PIC"
make -j$N -C ../phobos -f posix.mak MODEL=$MODEL PIC="$PIC"

Expand Down
183 changes: 144 additions & 39 deletions src/build.d
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Usage:
./build.d dmd

TODO:
- add different ENABLE modes
- add all posix.mak Makefile targets
- support 32-bit builds
- test on OSX
Expand Down Expand Up @@ -38,50 +37,93 @@ void main(string[] args)
"v", "Verbose command output", (cast(bool*) &verbose),
"f", "Force run (ignore timestamps and always run all tests)", (cast(bool*) &force),
);
if (res.helpWanted)
void showHelp()
{
defaultGetoptPrinter(`./build.d <targets>...

Examples:
Examples
--------

./build.d dmd # build DMD
./build.d unittest # runs internal unittests
./build.d clean # remove all generated files

Important variables:
--------------------

HOST_CXX: Host C++ compiler to use (g++,clang++)
HOST_DMD: Host D compiler to use for bootstrapping
AUTO_BOOTSTRAP: Enable auto-boostrapping by downloading a stable DMD binary
MODEL: Target architecture to build for (32,64) - defaults to the host architecture

Build modes:
------------
BUILD: release (default) | debug (enabled a build with debug instructions)

Opt-in build features:

ENABLE_RELEASE: Optimized release built
ENABLE_DEBUG: Add debug instructions and symbols (set if ENABLE_RELEASE isn't set)
ENABLE_WARNINGS: Enable C++ build warnings
ENABLE_PROFILING: Build dmd with a profiling recorder (C++)
ENABLE_PGO_USE: Build dmd with existing profiling information (C++)
PGO_DIR: Directory for profile-guided optimization (PGO) logs
ENABLE_LTO: Enable link-time optimizations
ENABLE_UNITTEST: Build dmd with unittests (sets ENABLE_COVERAGE=1)
ENABLE_PROFILE: Build dmd with a profiling recorder (D)
ENABLE_COVERAGE Build dmd with coverage counting
ENABLE_SANITIZERS Build dmd with sanitizer (e.g. ENABLE_SANITIZERS=address,undefined)

Targets
-------

./build.d dmd # build DMD
./build.d unittest # runs internal unittests
./build.d clean # remove all generated files
all Build dmd
unittest Run all unittest blocks
clean Remove all generated files

Options:
The generated files will be in generated/$(OS)/$(BUILD)/$(MODEL)

Command-line parameters
-----------------------
`, res.options);
"\nSee the README.md for a more in-depth explanation of the build script.".writeln;
return;
}

if (res.helpWanted)
return showHelp;

// parse arguments
args.popFront;
args2Environment(args);

// bootstrap all needed environment variables
env = getEnvironment;

// get all sources
sources = sourceFiles;

// default target
if (!args.length)
args = ["all"];

// bootstrap all needed environment variables
parseEnvironment;

auto targets = args
.predefinedTargets // preprocess
.array;

if (targets.length > 0)
processEnvironment;

// get all sources
sources = sourceFiles;

if (targets.length == 0)
return showHelp;

if (verbose)
{
if (verbose)
{
log("================================================================================");
foreach (key, value; env)
log("%s=%s", key, value);
log("================================================================================");
}
log("================================================================================");
foreach (key, value; env)
log("%s=%s", key, value);
log("================================================================================");
}
foreach (target; targets)
target();
}

/**
Expand Down Expand Up @@ -307,7 +349,7 @@ auto buildDMD()
Dependency dependency = {
// newdelete.o + lexer.a + backend.a
sources: sources.dmd.chain(sources.root, dependencys[0].targets, dependencys[1].targets, backend.targets).array,
target: env["G"].buildPath("dmd").exeName,
target: env["DMD_PATH"],
name: "(CC) MAIN_DMD_BUILD",
command: [
env["HOST_DMD_RUN"],
Expand All @@ -328,7 +370,8 @@ Special targets:
*/
auto predefinedTargets(string[] targets)
{
Appender!(string[]) newTargets;
import std.functional : toDelegate;
Appender!(void delegate()[]) newTargets;
foreach (t; targets)
{
t = t.buildNormalizedPath; // remove trailing slashes
Expand All @@ -343,7 +386,13 @@ auto predefinedTargets(string[] targets)
break;

case "unittest":
"TODO: unittest".writeln; // TODO
flags["DFLAGS"] ~= "-version=NoMain";
flags["DFLAGS"] ~= "-main";
flags["DFLAGS"] ~= "-unittest";
newTargets.put((){
buildDMD();
spawnProcess(env["DMD_PATH"]); // run the unittests
}.toDelegate);
break;

case "cxx-unittest":
Expand Down Expand Up @@ -376,7 +425,7 @@ auto predefinedTargets(string[] targets)

dmd:
case "dmd":
buildDMD();
newTargets.put({buildDMD();}.toDelegate);
break;

case "clean":
Expand All @@ -385,20 +434,20 @@ auto predefinedTargets(string[] targets)
exit(0);
break;

default:
case "all":
goto dmd;
default:
writefln("ERROR: Target `%s` is unknown.", t);
writeln;
break;
}
}
return newTargets.data;
}

// Sets the environment variables
string[string] getEnvironment()
void parseEnvironment()
{
string[string] env;

env.getDefault("TARGET_CPU", "X86");
auto os = env.getDefault("OS", detectOS);
auto build = env.getDefault("BUILD", "release");
Expand Down Expand Up @@ -448,7 +497,13 @@ string[string] getEnvironment()
env.getDefault("CXX_KIND", !cxxVersion.find("gcc", "Free Software")[0].empty ? "g++" : "clang++");

env.getDefault("HOST_DMD", "dmd");
}

// Checks the environment variables and flags
void processEnvironment()
{
auto model = env["MODEL"];
auto os = env["OS"];
// Auto-bootstrapping of a specific host compiler
if (env.getDefault("AUTO_BOOTSTRAP", "0") != "0")
{
Expand All @@ -471,8 +526,8 @@ string[string] getEnvironment()
}
else
{
env["HOST_DMD_PATH"] = ["which", env["HOST_DMD"]].execute.output.strip;
env["HOST_DMD_RUN"] = env["HOST_DMD"];
env["HOST_DMD_PATH"] = ["which", env["HOST_DMD"]].execute.output.strip.absolutePath;
env["HOST_DMD_RUN"] = env["HOST_DMD_PATH"];
}

if (!env["HOST_DMD_PATH"].exists)
Expand All @@ -491,6 +546,8 @@ string[string] getEnvironment()
else
enforce(0, "Invalid Host DMD found: " ~ hostDMDVersion);

env["DMD_PATH"] = env["G"].buildPath("dmd").exeName;

env.getDefault("ENABLE_WARNINGS", "0");
string[] warnings;
if (env["ENABLE_WARNINGS"] != "0")
Expand Down Expand Up @@ -550,12 +607,8 @@ string[string] getEnvironment()
if (env["CXX_KIND"] == "clang++")
cxxFlags ~= ["-xc++"];

flags["CXXFLAGS"] = cxxFlags;

// TODO: allow adding new flags from the environment
string[] dflags;
flags["DFLAGS"] ~= ["-version=MARS", "-w", "-de", env["PIC_FLAG"], env["MODEL_FLAG"]];
// TODO: add different ENABLE modes
string[] dflags = ["-version=MARS", "-w", "-de", env["PIC_FLAG"], env["MODEL_FLAG"]];

flags["BACK_FLAGS"] = ["-I"~env["ROOT"], "-I"~env["TK"], "-I"~env["C"], "-I"~env["G"], "-I"~env["D"], "-DDMDV2=1"];

Expand All @@ -564,7 +617,59 @@ string[string] getEnvironment()
version(OSX) version(X86_64)
dObjc = true;

return env;
if (env.getDefault("ENABLE_DEBUG", "0") != "0")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we copy the documentation comments for these from the Makefile? Or maybe put them in the help output? We should probably do the same for the targets as well. It's not a requirement for this PR, but eventually it'd be nice.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, some of these are only applicable to posix, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, some of these are only applicable to posix, right?

Yes, actually I'm not sure all of these modes even work on Posix (i.e. dmd still fails the test suite with ENABLE_DEBUG - #7528).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we copy the documentation comments for these from the Makefile? Or maybe put them in the help output?

Done.

{
cxxFlags ~= ["-g", "-g3", "-DDEBUG=1", "-DUNITTEST"];
dflags ~= ["-g", "-debug"];
}
if (env.getDefault("ENABLE_RELEASE", "0") != "0")
{
cxxFlags ~= ["-O2"];
dflags ~= ["-O", "-release", "-inline"];
}
else
{
// add debug symbols for all non-release builds
if (!dflags.canFind("-g"))
dflags ~= ["-g"];
}
if (env.getDefault("ENABLE_PROFILING", "0") != "0")
{
cxxFlags ~= ["-pg", "-fprofile-arcs", "-ftest-coverage"];
}
if (env.getDefault("ENABLE_PGO_GENERATE", "0") != "0")
{
enforce("PGO_DIR" in env, "No PGO_DIR variable set.");
cxxFlags ~= ["-fprofile-generate="~env["PGO_DIR"]];
}
if (env.getDefault("ENABLE_PGO_USE", "0") != "0")
{
enforce("PGO_DIR" in env, "No PGO_DIR variable set.");
cxxFlags ~= ["-fprofile-use="~env["PGO_DIR"], "-freorder-blocks-and-partition"];
}
if (env.getDefault("ENABLE_LTO", "0") != "0")
{
cxxFlags ~= ["-flto"];
}
if (env.getDefault("ENABLE_UNITTEST", "0") != "0")
{
dflags ~= ["-unittest", "-cov"];
}
if (env.getDefault("ENABLE_PROFILE", "0") != "0")
{
dflags ~= ["-profile"];
}
if (env.getDefault("ENABLE_COVERAGE", "0") != "0")
{
cxxFlags ~= ["--coverage"];
dflags ~= ["-cov", "-L-lgcov"];
}
if (env.getDefault("ENABLE_SANITIZERS", "0") != "0")
{
cxxFlags ~= ["-fsanitize="~env["ENABLE_SANITIZERS"]];
}
flags["DFLAGS"] ~= dflags;
flags["CXXFLAGS"] ~= cxxFlags;
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -598,7 +703,7 @@ auto sourceFiles()
frontend:
dirEntries(env["D"], "*.d", SpanMode.shallow)
.map!(e => e.name)
.filter!(e => !e.canFind("frontend.d"))
.filter!(e => !e.canFind("asttypename.d", "frontend.d"))
.array,
lexer: [
"console",
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/asttypename.d
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,6 @@ public :
unittest
{
import dmd.globals : Loc;
Expression e = new TypeidExp(Loc.init, null);
Expression e = new TypeidExp(Loc.initial, null);
assert(e.astTypeName == "TypeidExp");
}
18 changes: 5 additions & 13 deletions src/posix.mak
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
#
# HOST_CXX: Host C++ compiler to use (g++,clang++)
# HOST_DMD: Host D compiler to use for bootstrapping
# AUTO_BOOTSTRAP: Enable auto-boostrapping by download a stable DMD binary
# AUTO_BOOTSTRAP: Enable auto-boostrapping by downloading a stable DMD binary
# INSTALL_DIR: Installation folder to use
# MODEL: Target architecture to build for (32,64) - defaults to the host architecture
#
################################################################################
# Build modes:
# ------------
# BUILD: release (default) | debug (enabled a build with debug symbols)
# BUILD: release (default) | debug (enabled a build with debug instructions)
#
# Opt-in build features:
#
# ENABLE_RELEASE: Optimized release built (set by BUILD=release)
# ENABLE_DEBUG: Add debug instructions and symbols (set by BUILD=debug)
# ENABLE_RELEASE: Optimized release built
# ENABLE_DEBUG: Add debug instructions and symbols (set if ENABLE_RELEASE isn't set)
# ENABLE_WARNINGS: Enable C++ build warnings
# ENABLE_PROFILING: Build dmd with a profiling recorder (C++)
# ENABLE_PGO_USE: Build dmd with existing profiling information (C++)
Expand Down Expand Up @@ -231,15 +232,6 @@ override DFLAGS += -version=MARS $(PIC)
# Enable D warnings
override DFLAGS += -w -de

ifneq (,$(DEBUG))
ENABLE_DEBUG := 1
$(error 'DEBUG=1 has been removed. Please use ENABLE_DEBUG=1')
endif
ifneq (,$(RELEASE))
ENABLE_RELEASE := 1
$(error 'RELEASE=1 has been removed. Please use ENABLE_RELEASE=1')
endif

# Append different flags for debugging, profiling and release.
ifdef ENABLE_DEBUG
CXXFLAGS += -g -g3 -DDEBUG=1 -DUNITTEST
Expand Down