Merge branch 'master' into merge-2.072

Conflicts:
	runtime/CMakeLists.txt
This commit is contained in:
Martin 2017-02-07 20:20:38 +01:00
commit 03d59b7b96
8 changed files with 301 additions and 195 deletions

View file

@ -11,6 +11,7 @@ include(FindDCompiler)
include(CheckIncludeFile)
include(CheckLibraryExists)
include(CheckCXXCompilerFlag)
include(CheckDSourceCompiles)
# The script currently only supports the DMD-style commandline interface
if (NOT D_COMPILER_DMD_COMPAT)
@ -397,6 +398,11 @@ source_group("Header Files\\ir" FILES ${IR_HDR})
source_group("Generated Files" REGULAR_EXPRESSION "(id\\.[cdh]|impcnvtab\\.c)$")
#
# Configure the build system to use LTO and/or PGO while building LDC
#
include(HandleLTOPGOBuildOptions)
#
# Enable PGO if supported for this platform and LLVM version.
# LLVM >= 3.7 is required for PGO.

View file

@ -6,10 +6,10 @@
machine:
environment:
PATH: "~/$CIRCLE_PROJECT_REPONAME/ldc2-1.0.0-linux-x86_64/bin:$PATH"
PATH: "~/$CIRCLE_PROJECT_REPONAME/ldc2-1.1.0-linux-x86_64/bin:$PATH"
dependencies:
cache_directories:
- ldc2-1.0.0-linux-x86_64
- ldc2-1.1.0-linux-x86_64
#- clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-14.04
pre:
# LLVM's official APT repo:
@ -22,7 +22,7 @@ dependencies:
#- if [[ ! -e clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-14.04 ]]; then wget http://llvm.org/releases/3.8.0/clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz && xzcat clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | tar -xvf - ; fi
# Download and cache a prebuilt LDC package:
- if [[ ! -e ldc2-1.0.0-linux-x86_64/bin/ldc2 ]]; then wget https://github.com/ldc-developers/ldc/releases/download/v1.0.0/ldc2-1.0.0-linux-x86_64.tar.xz && xzcat ldc2-1.0.0-linux-x86_64.tar.xz | tar -xvf - ; fi
- if [[ ! -e ldc2-1.1.0-linux-x86_64/bin/ldc2 ]]; then wget https://github.com/ldc-developers/ldc/releases/download/v1.1.0/ldc2-1.1.0-linux-x86_64.tar.xz && xzcat ldc2-1.1.0-linux-x86_64.tar.xz | tar -xvf - ; fi
override:
- sudo apt-get remove clang llvm

View file

@ -0,0 +1,70 @@
# This file is modified from CMake's CheckCxxSourceCompiles.cmake.
# Distributed under the OSI-approved BSD 3-Clause License. See https://cmake.org/licensing for details.
# Check if given D source compiles and links into an executable
#
# CHECK_D_SOURCE_COMPILES(<code> <var> [FLAGS <flags>])
#
# ::
#
# <code> - source code to try to compile
# <var> - variable to store whether the source code compiled
# Will be created as an internal cache variable.
# <flags> - Extra commandline flags passed to the compiler.
#
# The D_COMPILER variable is read and must point to the D compiler executable.
macro(CHECK_D_SOURCE_COMPILES SOURCE VAR)
if(NOT DEFINED "${VAR}")
set(_FLAGS)
set(_key)
foreach(arg ${ARGN})
if("${arg}" MATCHES "^(FLAGS)$")
set(_key "${arg}")
elseif(_key)
list(APPEND _${_key} "${arg}")
set(_key 0)
else()
message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
endif()
endforeach()
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.d"
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Performing Test ${VAR}")
endif()
execute_process(COMMAND ${D_COMPILER} ${_FLAGS} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.d
OUTPUT_VARIABLE OUTPUT
ERROR_VARIABLE OUTPUT
RESULT_VARIABLE RETVAL)
if(${RETVAL})
set(${VAR} 0)
else()
set(${VAR} 1)
endif()
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Performing Test ${VAR} - Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing D SOURCE FILE Test ${VAR} succeeded with the following output:\n"
"${OUTPUT}\n"
"Source was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Performing Test ${VAR} - Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing D SOURCE FILE Test ${VAR} failed with the following output:\n"
"${OUTPUT}\n"
"Source was:\n${SOURCE}\n")
endif()
endif()
endmacro()

View file

@ -0,0 +1,46 @@
# Handles the LDC_BUILD_WITH_LTO build option.
# For example `cmake -DLDC_BUILD_WITH_LTO=thin`.
#
# LTO is enabled for the C++ and D compilers, provided that they accept the `-flto` flag.
# TODO: implement a LDC_BUILD_WITH_PGO build option (or something similar) to generate/use an LDC PGO profile.
set(__LTO_FLAG)
set(LDC_BUILD_WITH_LTO OFF CACHE STRING "Build LDC with LTO. May be specified as Thin or Full to use a particular kind of LTO")
string(TOUPPER "${LDC_BUILD_WITH_LTO}" uppercase_LDC_BUILD_WITH_LTO)
if(uppercase_LDC_BUILD_WITH_LTO STREQUAL "THIN")
set(__LTO_FLAG "-flto=thin")
elseif(uppercase_LDC_BUILD_WITH_LTO STREQUAL "FULL")
set(__LTO_FLAG "-flto=full")
elseif(LDC_BUILD_WITH_LTO)
set(__LTO_FLAG "-flto")
endif()
if(__LTO_FLAG)
message(STATUS "Building LDC using LTO: ${__LTO_FLAG}")
check_cxx_compiler_flag(${__LTO_FLAG} CXX_COMPILER_ACCEPTS_FLTO_${uppercase_LDC_BUILD_WITH_LTO})
if (CXX_COMPILER_ACCEPTS_FLTO_${uppercase_LDC_BUILD_WITH_LTO})
append(${__LTO_FLAG} CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
endif()
check_d_source_compiles("void main(){}" D_COMPILER_ACCEPTS_FLTO_${uppercase_LDC_BUILD_WITH_LTO} FLAGS ${__LTO_FLAG})
if(D_COMPILER_ACCEPTS_FLTO_${uppercase_LDC_BUILD_WITH_LTO})
append(${__LTO_FLAG} DDMD_DFLAGS)
endif()
if(uppercase_LDC_BUILD_WITH_LTO STREQUAL "THIN")
# On darwin, enable the lto cache.
if(APPLE)
append("-Wl,-cache_path_lto,${PROJECT_BINARY_DIR}/lto.cache" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
endif()
endif()
if(uppercase_LDC_BUILD_WITH_LTO MATCHES "^(THIN|FULL)$")
if (APPLE)
# Explicitly use the LTO library that shipped with the host LDC, assuming it is newer than the system-installed lib.
get_filename_component(HOST_LDC_BINDIR ${D_COMPILER} DIRECTORY)
if(EXISTS ${HOST_LDC_BINDIR}/../lib/libLTO-ldc.dylib)
message(STATUS "Using ${HOST_LDC_BINDIR}/../lib/libLTO-ldc.dylib for LTO")
append("-Wl,-lto_library,${HOST_LDC_BINDIR}/../lib/libLTO-ldc.dylib" CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS)
endif()
endif()
endif()
endif()

View file

@ -216,6 +216,9 @@ bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e,
///
DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
Expressions *arguments, LLValue *sretPointer = nullptr);
DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
const std::vector<DValue *> &argvals,
LLValue *sretPointer = nullptr);
Type *stripModifiers(Type *type, bool transitive = false);

View file

@ -208,7 +208,8 @@ static void addExplicitArguments(std::vector<LLValue *> &args, AttrSet &attrs,
////////////////////////////////////////////////////////////////////////////////
static LLValue *getTypeinfoArrayArgumentForDVarArg(Expressions *arguments,
static LLValue *
getTypeinfoArrayArgumentForDVarArg(const std::vector<DValue *> &argvals,
int begin) {
IF_LOG Logger::println("doing d-style variadic arguments");
LOG_SCOPE
@ -216,10 +217,7 @@ static LLValue *getTypeinfoArrayArgumentForDVarArg(Expressions *arguments,
// number of non variadic args
IF_LOG Logger::println("num non vararg params = %d", begin);
// get n args in arguments list
size_t n_arguments = arguments ? arguments->dim : 0;
const size_t numVariadicArgs = n_arguments - begin;
const size_t numVariadicArgs = argvals.size() - begin;
// build type info array
LLType *typeinfotype = DtoType(Type::dtypeinfo->type);
@ -232,9 +230,9 @@ static LLValue *getTypeinfoArrayArgumentForDVarArg(Expressions *arguments,
IF_LOG Logger::cout() << "_arguments storage: " << *typeinfomem << '\n';
std::vector<LLConstant *> vtypeinfos;
vtypeinfos.reserve(n_arguments);
for (size_t i = begin; i < n_arguments; i++) {
vtypeinfos.push_back(DtoTypeInfoOf((*arguments)[i]->type));
vtypeinfos.reserve(argvals.size());
for (size_t i = begin; i < argvals.size(); i++) {
vtypeinfos.push_back(DtoTypeInfoOf(argvals[i]->type));
}
// apply initializer
@ -634,13 +632,15 @@ public:
ImplicitArgumentsBuilder(std::vector<LLValue *> &args, AttrSet &attrs,
Loc &loc, DValue *fnval,
LLFunctionType *llCalleeType, Expressions *arguments,
LLFunctionType *llCalleeType,
const std::vector<DValue *> &argvals,
Type *resulttype, LLValue *sretPointer)
: args(args), attrs(attrs), loc(loc), fnval(fnval), arguments(arguments),
: args(args), attrs(attrs), loc(loc), fnval(fnval), argvals(argvals),
resulttype(resulttype), sretPointer(sretPointer),
// computed:
calleeType(fnval->type), dfnval(fnval->isFunc()),
irFty(DtoIrTypeFunction(fnval)), tf(DtoTypeFunction(fnval)),
isDelegateCall(fnval->type->toBasetype()->ty == Tdelegate),
dfnval(fnval->isFunc()), irFty(DtoIrTypeFunction(fnval)),
tf(DtoTypeFunction(fnval)),
llArgTypesBegin(llCalleeType->param_begin()) {}
void addImplicitArgs() {
@ -661,12 +661,12 @@ private:
AttrSet &attrs;
Loc &loc;
DValue *const fnval;
Expressions *const arguments;
const std::vector<DValue *> &argvals;
Type *const resulttype;
LLValue *const sretPointer;
// computed:
Type *const calleeType;
const bool isDelegateCall;
DFuncValue *const dfnval;
IrFuncTy &irFty;
TypeFunction *const tf;
@ -700,10 +700,9 @@ private:
// Adds an optional context/this pointer argument.
void addContext() {
bool thiscall = irFty.arg_this;
bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate);
bool nestedcall = irFty.arg_nest;
if (!thiscall && !delegatecall && !nestedcall)
if (!thiscall && !isDelegateCall && !nestedcall)
return;
size_t index = args.size();
@ -734,7 +733,7 @@ private:
// ... or a normal 'this' argument
LLValue *thisarg = DtoBitCast(dfnval->vthis, llArgType);
args.push_back(thisarg);
} else if (delegatecall) {
} else if (isDelegateCall) {
// ... or a delegate context arg
LLValue *ctxarg;
if (fnval->isLVal()) {
@ -767,7 +766,7 @@ private:
if (irFty.arg_objcSelector && dfnval) {
if (auto sel = dfnval->func->objc.selector) {
LLGlobalVariable* selptr = objc_getMethVarRef(*sel);
LLGlobalVariable *selptr = objc_getMethVarRef(*sel);
args.push_back(DtoBitCast(DtoLoad(selptr), getVoidPtrType()));
hasObjcSelector = true;
}
@ -782,7 +781,7 @@ private:
int numFormalParams = Parameter::dim(tf->parameters);
LLValue *argumentsArg =
getTypeinfoArrayArgumentForDVarArg(arguments, numFormalParams);
getTypeinfoArrayArgumentForDVarArg(argvals, numFormalParams);
args.push_back(argumentsArg);
attrs.add(args.size(), irFty.arg_arguments->attrs);
@ -791,18 +790,17 @@ private:
////////////////////////////////////////////////////////////////////////////////
namespace {
// FIXME: this function is a mess !
DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
Expressions *arguments, LLValue *sretPointer) {
IF_LOG Logger::println("DtoCallFunction()");
LOG_SCOPE
DValue *DtoCallFunctionImpl(Loc &loc, Type *resulttype, DValue *fnval,
const std::vector<DValue *> &argvals,
LLValue *sretPointer) {
// make sure the D callee type has been processed
DtoType(fnval->type);
// get func value if any
DFuncValue *dfnval = fnval->isFunc();
DFuncValue *const dfnval = fnval->isFunc();
// get function type info
IrFuncTy &irFty = DtoIrTypeFunction(fnval);
@ -834,7 +832,7 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
args.reserve(irFty.args.size());
// handle implicit arguments (sret, context/this, _arguments)
ImplicitArgumentsBuilder iab(args, attrs, loc, fnval, callableTy, arguments,
ImplicitArgumentsBuilder iab(args, attrs, loc, fnval, callableTy, argvals,
resulttype, sretPointer);
iab.addImplicitArgs();
@ -853,34 +851,6 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
}
const int numFormalParams = Parameter::dim(tf->parameters); // excl. variadics
const size_t n_arguments =
arguments ? arguments->dim : 0; // number of explicit arguments
std::vector<DValue *> argvals(n_arguments, static_cast<DValue *>(nullptr));
if (dfnval && dfnval->func && dfnval->func->isArrayOp) {
// For array ops, the druntime implementation signatures are crafted
// specifically such that the evaluation order is as expected with
// the strange DMD reverse parameter passing order. Thus, we need
// to actually build the arguments right-to-left for them.
for (int i = numFormalParams - 1; i >= 0; --i) {
Parameter *fnarg = Parameter::getNth(tf->parameters, i);
assert(fnarg);
DValue *argval = DtoArgument(fnarg, (*arguments)[i]);
argvals[i] = argval;
}
} else {
for (int i = 0; i < numFormalParams; ++i) {
Parameter *fnarg = Parameter::getNth(tf->parameters, i);
assert(fnarg);
DValue *argval = DtoArgument(fnarg, (*arguments)[i]);
argvals[i] = argval;
}
}
// add varargs
for (size_t i = numFormalParams; i < n_arguments; ++i) {
argvals[i] = DtoArgument(nullptr, (*arguments)[i]);
}
addExplicitArguments(args, attrs, irFty, callableTy, argvals,
numFormalParams);
@ -911,7 +881,8 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
: 0);
LLValue *retllval =
(irFty.arg_sret ? args[sretArgIndex] : call.getInstruction());
bool retValIsLVal = (tf->isref && returnTy != Tvoid) || (irFty.arg_sret != nullptr);
bool retValIsLVal =
(tf->isref && returnTy != Tvoid) || (irFty.arg_sret != nullptr);
if (!retValIsLVal) {
// let the ABI transform the return value back
@ -1044,3 +1015,57 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
return new DImValue(resulttype, retllval);
}
std::vector<DValue *> evaluateArgExpressions(DValue *fnval,
Expressions *arguments) {
IF_LOG Logger::println("Evaluating argument expressions");
LOG_SCOPE
const auto tf = DtoTypeFunction(fnval);
const size_t numArguments = arguments ? arguments->dim : 0;
std::vector<DValue *> argvals(numArguments);
// For array ops, the druntime implementation signatures are crafted
// specifically such that the evaluation order is as expected with
// the strange DMD reverse parameter passing order. Thus, we need
// to actually evaluate the arguments right-to-left for them.
const auto dfnval = fnval->isFunc();
const bool reverse = (dfnval && dfnval->func && dfnval->func->isArrayOp);
// formal params (excl. variadics)
const size_t numFormalParams = Parameter::dim(tf->parameters);
for (size_t j = 0; j < numFormalParams; ++j) {
size_t i = (!reverse ? j : numFormalParams - 1 - j);
Parameter *fnarg = Parameter::getNth(tf->parameters, i);
assert(fnarg);
argvals[i] = DtoArgument(fnarg, (*arguments)[i]);
}
// append variadics
for (size_t i = numFormalParams; i < numArguments; ++i) {
argvals[i] = DtoArgument(nullptr, (*arguments)[i]);
}
return argvals;
}
} // anonymous namespace
DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
const std::vector<DValue *> &argvals,
LLValue *sretPointer) {
IF_LOG Logger::println("DtoCallFunction()");
LOG_SCOPE
return DtoCallFunctionImpl(loc, resulttype, fnval, argvals, sretPointer);
}
DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
Expressions *arguments, llvm::Value *sretPointer) {
IF_LOG Logger::println("DtoCallFunction()");
LOG_SCOPE
const auto argvals = evaluateArgExpressions(fnval, arguments);
return DtoCallFunctionImpl(loc, resulttype, fnval, argvals, sretPointer);
}

View file

@ -78,7 +78,7 @@ void checkStructElems(StructLiteralExp *sle, ArrayParam<Type *> elemTypes) {
}
for (size_t i = 0; i < sle->elements->dim; ++i) {
if ((*sle->elements)[i]->type != elemTypes[i]) {
if ((*sle->elements)[i]->type->toBasetype() != elemTypes[i]) {
sle->error("invalid field type in 'ldc.attributes.%s'; does druntime not "
"match compiler version?",
sle->sd->ident->toChars());

View file

@ -1,6 +1,6 @@
project(runtime)
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 2.8.5)
#
# Main configuration.
@ -53,14 +53,20 @@ set(PROFILERT_DIR ${PROJECT_SOURCE_DIR}/profile-rt CACHE PATH "profile-rt root d
# Gather source files.
#
file(GLOB CORE_D ${RUNTIME_DIR}/src/core/*.d)
file(GLOB_RECURSE CORE_D_INTERNAL ${RUNTIME_DIR}/src/core/internal/*.d)
file(GLOB CORE_D_SYNC ${RUNTIME_DIR}/src/core/sync/*.d)
file(GLOB CORE_D_STDC ${RUNTIME_DIR}/src/core/stdc/*.d)
file(GLOB_RECURSE GC_D ${RUNTIME_DIR}/src/gc/*.d)
file(GLOB_RECURSE DCRT_D ${RUNTIME_DIR}/src/rt/*.d)
file(GLOB_RECURSE LDC_D ${RUNTIME_DIR}/src/ldc/*.d)
list(REMOVE_ITEM DCRT_D
# druntime D parts
file(GLOB_RECURSE DRUNTIME_D ${RUNTIME_DIR}/src/*.d)
list(REMOVE_ITEM DRUNTIME_D ${RUNTIME_DIR}/src/test_runner.d)
# remove unsupported etc/linux/memoryerror.d (see issue #1915)
list(REMOVE_ITEM DRUNTIME_D ${RUNTIME_DIR}/src/etc/linux/memoryerror.d)
# FIXME: Remove all modules in core/stdcpp/ due to alpha quality.
# See PR #1917; partly fixed upstream.
file(GLOB_RECURSE DRUNTIME_D_STDCPP ${RUNTIME_DIR}/src/core/stdcpp/*.d)
list(REMOVE_ITEM DRUNTIME_D ${DRUNTIME_D_STDCPP})
# remove all modules in gcstub/
file(GLOB_RECURSE DRUNTIME_D_GCSTUB ${RUNTIME_DIR}/src/gcstub/*.d)
list(REMOVE_ITEM DRUNTIME_D ${DRUNTIME_D_GCSTUB})
# remove some modules in rt/
list(REMOVE_ITEM DRUNTIME_D
${RUNTIME_DIR}/src/rt/alloca.d
${RUNTIME_DIR}/src/rt/deh.d
${RUNTIME_DIR}/src/rt/deh_win32.d
@ -69,120 +75,85 @@ list(REMOVE_ITEM DCRT_D
${RUNTIME_DIR}/src/rt/llmath.d
${RUNTIME_DIR}/src/rt/trace.d
)
file(GLOB DCRT_C ${RUNTIME_DIR}/src/rt/*.c)
list(REMOVE_ITEM DCRT_C ${RUNTIME_DIR}/src/rt/deh.c ${RUNTIME_DIR}/src/rt/dylib_fixes.c)
if(NOT APPLE)
list(REMOVE_ITEM DCRT_C ${RUNTIME_DIR}/src/rt/osx_tls.c)
endif()
if(MSVC)
list(APPEND DCRT_C ${RUNTIME_DIR}/src/ldc/msvc.c)
else()
list(REMOVE_ITEM DCRT_C ${RUNTIME_DIR}/src/rt/msvc.c)
list(REMOVE_ITEM DCRT_C ${RUNTIME_DIR}/src/rt/msvc_math.c)
list(REMOVE_ITEM DCRT_C ${RUNTIME_DIR}/src/rt/stdio_msvc.c)
endif()
file(GLOB_RECURSE CORE_D_UNIX ${RUNTIME_DIR}/src/core/sys/posix/*.d)
file(GLOB_RECURSE CORE_D_FREEBSD ${RUNTIME_DIR}/src/core/sys/freebsd/*.d)
file(GLOB_RECURSE CORE_D_NETBSD ${RUNTIME_DIR}/src/core/sys/netbsd/*.d)
file(GLOB_RECURSE CORE_D_LINUX ${RUNTIME_DIR}/src/core/sys/linux/*.d)
file(GLOB_RECURSE CORE_D_OSX ${RUNTIME_DIR}/src/core/sys/osx/*.d)
file(GLOB_RECURSE CORE_D_SOLARIS ${RUNTIME_DIR}/src/core/sys/solaris/*.d)
file(GLOB_RECURSE CORE_D_WIN ${RUNTIME_DIR}/src/core/sys/windows/*.d)
set(CORE_D_SYS)
set(DCRT_ASM)
# only include core/sys/ modules matching the platform
file(GLOB_RECURSE DRUNTIME_D_BIONIC ${RUNTIME_DIR}/src/core/sys/bionic/*.d)
file(GLOB_RECURSE DRUNTIME_D_FREEBSD ${RUNTIME_DIR}/src/core/sys/freebsd/*.d)
file(GLOB_RECURSE DRUNTIME_D_LINUX ${RUNTIME_DIR}/src/core/sys/linux/*.d)
file(GLOB_RECURSE DRUNTIME_D_OSX ${RUNTIME_DIR}/src/core/sys/osx/*.d)
file(GLOB_RECURSE DRUNTIME_D_POSIX ${RUNTIME_DIR}/src/core/sys/posix/*.d)
file(GLOB_RECURSE DRUNTIME_D_SOLARIS ${RUNTIME_DIR}/src/core/sys/solaris/*.d)
file(GLOB_RECURSE DRUNTIME_D_WINDOWS ${RUNTIME_DIR}/src/core/sys/windows/*.d)
list(REMOVE_ITEM DRUNTIME_D
${DRUNTIME_D_BIONIC} ${DRUNTIME_D_FREEBSD} ${DRUNTIME_D_LINUX} ${DRUNTIME_D_OSX}
${DRUNTIME_D_POSIX} ${DRUNTIME_D_SOLARIS} ${DRUNTIME_D_WINDOWS}
)
if(UNIX)
list(APPEND CORE_D_SYS ${CORE_D_UNIX})
if(${CMAKE_SYSTEM} MATCHES "FreeBSD")
list(APPEND CORE_D_SYS ${CORE_D_FREEBSD})
endif()
if(${CMAKE_SYSTEM} MATCHES "NetBSD")
list(APPEND CORE_D_SYS ${CORE_D_NETBSD})
endif()
if(${CMAKE_SYSTEM} MATCHES "Linux")
list(APPEND CORE_D_SYS ${CORE_D_LINUX})
endif()
if(${CMAKE_SYSTEM} MATCHES "SunOS")
list(APPEND CORE_D_SYS ${CORE_D_SOLARIS})
endif()
# Assembler support was rewritten in CMake 2.8.5.
# The assembler file must be passed to gcc but prior to this
# version it is passed to as. This results in a bunch of
# error message. This is only critical for non-x86 platforms.
# On x86/x86-64 the file can safely be ignored.
if("${CMAKE_VERSION}" MATCHES "^2\\.8\\.[01234]($|\\..*)")
message(WARNING "Excluding core/threadasm.S from build because of missing CMake support.")
message(WARNING "This file is required for certain non-x86 platforms.")
message(WARNING "Please consider updating CMake to at least 2.8.5.")
else()
list(APPEND DCRT_ASM ${RUNTIME_DIR}/src/core/threadasm.S)
list(APPEND DCRT_ASM ${RUNTIME_DIR}/src/ldc/eh_asm.S)
endif()
list(APPEND DRUNTIME_D ${DRUNTIME_D_POSIX})
if(APPLE)
list(APPEND CORE_D_SYS ${CORE_D_OSX})
list(APPEND DRUNTIME_D ${DRUNTIME_D_OSX})
elseif(${CMAKE_SYSTEM} MATCHES "FreeBSD")
list(APPEND DRUNTIME_D ${DRUNTIME_D_FREEBSD})
elseif(${CMAKE_SYSTEM} MATCHES "Linux")
list(APPEND DRUNTIME_D ${DRUNTIME_D_LINUX})
list(APPEND DRUNTIME_D ${DRUNTIME_D_BIONIC})
elseif(${CMAKE_SYSTEM} MATCHES "SunOS")
list(APPEND DRUNTIME_D ${DRUNTIME_D_SOLARIS})
endif()
# Using CMAKE_SYSTEM_PROCESSOR might be inacurrate when somebody is
# cross-compiling by just setting the tool executbles to a cross toolchain,
# so just always include the file.
list(APPEND DCRT_C ${RUNTIME_DIR}/src/ldc/arm_unwind.c)
elseif(WIN32)
list(APPEND CORE_D_SYS ${CORE_D_WIN})
list(REMOVE_ITEM DCRT_C ${RUNTIME_DIR}/src/rt/monitor.c)
list(REMOVE_ITEM DCRT_C ${RUNTIME_DIR}/src/rt/bss_section.c)
list(APPEND DRUNTIME_D ${DRUNTIME_D_WINDOWS})
endif()
# druntime C parts
file(GLOB_RECURSE DRUNTIME_C ${RUNTIME_DIR}/src/*.c)
list(REMOVE_ITEM DRUNTIME_C ${RUNTIME_DIR}/src/rt/dylib_fixes.c)
if(NOT APPLE)
list(REMOVE_ITEM DRUNTIME_C ${RUNTIME_DIR}/src/rt/osx_tls.c)
endif()
if(NOT MSVC)
list(REMOVE_ITEM DRUNTIME_C ${RUNTIME_DIR}/src/rt/msvc.c ${RUNTIME_DIR}/src/rt/msvc_math.c)
endif()
# druntime ASM parts
set(DRUNTIME_ASM)
if(UNIX)
list(APPEND DRUNTIME_ASM ${RUNTIME_DIR}/src/core/threadasm.S ${RUNTIME_DIR}/src/ldc/eh_asm.S)
endif()
list(APPEND CORE_D ${CORE_D_INTERNAL} ${CORE_D_SYNC} ${CORE_D_SYS} ${CORE_D_STDC})
list(APPEND CORE_D ${LDC_D} ${RUNTIME_DIR}/src/object.d)
file(GLOB CORE_C ${RUNTIME_DIR}/src/core/stdc/*.c)
if(PHOBOS2_DIR)
file(GLOB PHOBOS2_D ${PHOBOS2_DIR}/std/*.d)
file(GLOB PHOBOS2_D_ALGORITHM ${PHOBOS2_DIR}/std/algorithm/*.d)
file(GLOB PHOBOS2_D_CONTAINER ${PHOBOS2_DIR}/std/container/*.d)
file(GLOB PHOBOS2_D_DIGEST ${PHOBOS2_DIR}/std/digest/*.d)
file(GLOB_RECURSE PHOBOS2_D_EXPERIMENTAL ${PHOBOS2_DIR}/std/experimental/*.d)
file(GLOB PHOBOS2_D_NET ${PHOBOS2_DIR}/std/net/*.d)
file(GLOB PHOBOS2_D_RANGE ${PHOBOS2_DIR}/std/range/*.d)
file(GLOB_RECURSE PHOBOS2_D_REGEX ${PHOBOS2_DIR}/std/regex/*.d)
file(GLOB_RECURSE PHOBOS2_D_INTERNAL ${PHOBOS2_DIR}/std/internal/*.d)
file(GLOB PHOBOS2_D_C ${PHOBOS2_DIR}/std/c/*.d)
file(GLOB PHOBOS2_ETC ${PHOBOS2_DIR}/etc/c/*.d)
if(APPLE)
file(GLOB PHOBOS2_D_C_SYS ${PHOBOS2_DIR}/std/c/osx/*.d)
elseif(FreeBSD)
file(GLOB PHOBOS2_D_C_SYS ${PHOBOS2_DIR}/std/c/freebsd/*.d)
elseif(UNIX)
# Install Linux headers on all non-Apple *nixes - not correct, but
# shouldn't cause any harm either.
file(GLOB PHOBOS2_D_C_SYS ${PHOBOS2_DIR}/std/c/linux/*.d)
elseif(WIN32)
file(GLOB PHOBOS2_D_C_SYS ${PHOBOS2_DIR}/std/c/windows/*.d)
endif()
file(GLOB ZLIB_C ${PHOBOS2_DIR}/etc/c/zlib/*.c)
list(REMOVE_ITEM ZLIB_C
${PHOBOS2_DIR}/etc/c/zlib/minigzip.c
${PHOBOS2_DIR}/etc/c/zlib/example.c
${PHOBOS2_DIR}/etc/c/zlib/gzio.c
)
if(WIN32)
file(GLOB PHOBOS2_D_WIN ${PHOBOS2_DIR}/std/windows/*.d)
endif()
list(APPEND PHOBOS2_D
${PHOBOS2_D_ALGORITHM}
${PHOBOS2_D_CONTAINER}
${PHOBOS2_D_DIGEST}
${PHOBOS2_D_EXPERIMENTAL}
${PHOBOS2_D_NET}
${PHOBOS2_D_RANGE}
${PHOBOS2_D_REGEX}
${PHOBOS2_D_INTERNAL}
${PHOBOS2_D_WIN}
${PHOBOS2_D_C}
${PHOBOS2_D_C_SYS}
${PHOBOS2_ETC}
)
# Phobos D parts
file(GLOB_RECURSE PHOBOS2_D ${PHOBOS2_DIR}/*.d)
# remove top-level modules index.d and unittest.d
list(REMOVE_ITEM PHOBOS2_D ${PHOBOS2_DIR}/index.d ${PHOBOS2_DIR}/unittest.d)
# only include std/c/ modules matching the platform
file(GLOB_RECURSE PHOBOS2_D_FREEBSD ${PHOBOS2_DIR}/std/c/freebsd/*.d)
file(GLOB_RECURSE PHOBOS2_D_LINUX ${PHOBOS2_DIR}/std/c/linux/*.d)
file(GLOB_RECURSE PHOBOS2_D_OSX ${PHOBOS2_DIR}/std/c/osx/*.d)
file(GLOB_RECURSE PHOBOS2_D_WINDOWS ${PHOBOS2_DIR}/std/c/windows/*.d)
list(REMOVE_ITEM PHOBOS2_D
${PHOBOS2_DIR}/std/intrinsic.d
${PHOBOS2_D_FREEBSD} ${PHOBOS2_D_LINUX} ${PHOBOS2_D_OSX} ${PHOBOS2_D_WINDOWS}
)
if(UNIX)
if(APPLE)
list(APPEND PHOBOS2_D ${PHOBOS2_D_OSX})
elseif(${CMAKE_SYSTEM} MATCHES "FreeBSD")
list(APPEND PHOBOS2_D ${PHOBOS2_D_FREEBSD})
elseif(${CMAKE_SYSTEM} MATCHES "Linux")
list(APPEND PHOBOS2_D ${PHOBOS2_D_LINUX})
endif()
elseif(WIN32)
list(APPEND PHOBOS2_D ${PHOBOS2_D_WINDOWS})
endif()
# only include std/windows/ modules on Windows
if(NOT WIN32)
file(GLOB_RECURSE PHOBOS2_D_WINDOWS ${PHOBOS2_DIR}/std/windows/*.d)
list(REMOVE_ITEM PHOBOS2_D ${PHOBOS2_D_WINDOWS})
endif()
# Phobos C parts
file(GLOB_RECURSE PHOBOS2_C ${PHOBOS2_DIR}/*.c)
# remove some obsolete zlib modules
list(REMOVE_ITEM PHOBOS2_C ${PHOBOS2_DIR}/etc/c/zlib/minigzip.c ${PHOBOS2_DIR}/etc/c/zlib/example.c)
set(CONFIG_NAME ${LDC_EXE}_phobos)
else()
set(CONFIG_NAME ${LDC_EXE})
@ -339,29 +310,13 @@ endmacro()
macro(compile_druntime d_flags lib_suffix path_suffix outlist_o outlist_bc)
get_target_suffix("${lib_suffix}" "${path_suffix}" target_suffix)
# Always disable invariants for debug builds of core.* and gc.* (there
# are/were some broken invariants around; druntime is always built in
# release mode in upstream builds).
set(rt_flags "${d_flags};-disable-invariants")
if(BUILD_SHARED_LIBS)
set(shared ";-d-version=Shared")
else()
set(shared)
endif()
foreach(f ${CORE_D} ${GC_D})
dc(
${f}
"${rt_flags}${shared}"
"${RUNTIME_DIR}"
"${target_suffix}"
${outlist_o}
${outlist_bc}
)
endforeach()
foreach(f ${DCRT_D})
foreach(f ${DRUNTIME_D})
dc(
${f}
"${d_flags}${shared}"
@ -400,7 +355,7 @@ macro(build_runtime d_flags c_flags ld_flags lib_suffix path_suffix outlist_targ
compile_druntime("${d_flags}" "${lib_suffix}" "${path_suffix}" druntime_o druntime_bc)
add_library(druntime-ldc${target_suffix} ${D_LIBRARY_TYPE}
${druntime_o} ${CORE_C} ${DCRT_C} ${DCRT_ASM})
${druntime_o} ${DRUNTIME_C} ${DRUNTIME_ASM})
set_target_properties(
druntime-ldc${target_suffix} PROPERTIES
OUTPUT_NAME druntime-ldc${lib_suffix}
@ -434,7 +389,8 @@ macro(build_runtime d_flags c_flags ld_flags lib_suffix path_suffix outlist_targ
set(phobos2_bc "")
compile_phobos2("${d_flags}" "${lib_suffix}" "${path_suffix}" phobos2_o phobos2_bc)
add_library(phobos2-ldc${target_suffix} ${D_LIBRARY_TYPE} ${ZLIB_C} ${phobos2_o})
add_library(phobos2-ldc${target_suffix} ${D_LIBRARY_TYPE}
${phobos2_o} ${PHOBOS2_C})
set_target_properties(
phobos2-ldc${target_suffix} PROPERTIES
OUTPUT_NAME phobos2-ldc${lib_suffix}
@ -722,7 +678,7 @@ function(add_tests d_files runner target_suffix)
endfunction()
function(add_runtime_tests name_suffix path_suffix)
get_target_suffix("${name_suffix}" "${path_suffix}" target_suffix)
add_tests("${CORE_D};${DCRT_D};${GC_D}" "druntime" "${target_suffix}")
add_tests("${DRUNTIME_D}" "druntime" "${target_suffix}")
if(PHOBOS2_DIR)
add_tests("${PHOBOS2_D}" "phobos2" "${target_suffix}")
endif()