Simplify CMakeLists.txt.

This version works with LLVM 3.0 and 3.1.
This commit is contained in:
kai 2012-07-24 23:33:15 +02:00
parent 1c1c6894e0
commit 508dd9ff70
5 changed files with 229 additions and 188 deletions

View file

@ -7,18 +7,11 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")
# Locate LLVM. # Locate LLVM.
# #
# This would actually better be named named EXTRA_LLVM_TARGETS, as it allows
# additional targets (beside the native one) to be specified. It affects the
# LLVM libraries linked and is converted to a preprocessor define used in
# gen/main.cpp.
set(EXTRA_LLVM_MODULES "" CACHE STRING
"Extra LLVM targets to link in (see llvm-config --targets-built)")
separate_arguments(EXTRA_LLVM_MODULES)
# We need to find exactly the right LLVM version, our code usually does not # We need to find exactly the right LLVM version, our code usually does not
# work across LLVM »minor« releases. # work across LLVM »minor« releases.
find_package(LLVM 3.0 EXACT REQUIRED find_package(LLVM 3.0 EXACT REQUIRED
bitwriter linker ipo instrumentation backend ${EXTRA_LLVM_MODULES}) all-targets bitwriter linker ipo instrumentation backend ${EXTRA_LLVM_MODULES})
math(EXPR LDC_LLVM_VER ${LLVM_VERSION_MAJOR}*100+${LLVM_VERSION_MINOR})
# #
# Locate libconfig++. # Locate libconfig++.
@ -94,7 +87,7 @@ set_target_properties(
idgen impcnvgen PROPERTIES idgen impcnvgen PROPERTIES
LINKER_LANGUAGE CXX LINKER_LANGUAGE CXX
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${DMDFE_PATH} RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${DMDFE_PATH}
COMPILE_FLAGS ${LLVM_CXXFLAGS} COMPILE_FLAGS "${LLVM_CXXFLAGS}"
) )
get_target_property(IDGEN_LOC idgen LOCATION) get_target_property(IDGEN_LOC idgen LOCATION)
get_target_property(IMPCNVGEN_LOC impcnvgen LOCATION) get_target_property(IMPCNVGEN_LOC impcnvgen LOCATION)
@ -123,68 +116,6 @@ set(LDC_GENERATED
${PROJECT_BINARY_DIR}/${DMDFE_PATH}/impcnvtab.c ${PROJECT_BINARY_DIR}/${DMDFE_PATH}/impcnvtab.c
) )
#
# Set up target defines.
#
set(DEFAULT_TARGET ${LLVM_HOST_TARGET} CACHE STRING "default target")
add_definitions(-DDEFAULT_TARGET_TRIPLE="${DEFAULT_TARGET}")
# Generate the alternate target triple (x86 on x86_64 and vice versa.)
if(LLVM_HOST_TARGET MATCHES "i[3-9]86-")
string(REGEX REPLACE "^i[3-9]86-(.*)" "x86_64-\\1" HOST_ALT_TARGET ${LLVM_HOST_TARGET})
elseif(LLVM_HOST_TARGET MATCHES "^x86_64-.*")
string(REGEX REPLACE "^x86_64-(.*)" "i686-\\1" HOST_ALT_TARGET ${LLVM_HOST_TARGET})
endif()
set(DEFAULT_ALT_TARGET ${HOST_ALT_TARGET} CACHE STRING "default alt target")
add_definitions(-DDEFAULT_ALT_TARGET_TRIPLE="${DEFAULT_ALT_TARGET}")
#
# Detect host architecture.
# The code borrowed from llvm's config-x.cmake.
#
# This is only needed to initialize the llvm native target which is
# exactly the purpose of llvm::InitializeNativeTarget* functions.
# Unfortunately, there is a bug in llvm's cmake script that prevents
# the asm parser from being initialized when the functions are used.
# So we have to do the dirty work ourselves.
string(REGEX MATCH "^[^-]*" HOST_ARCH ${LLVM_HOST_TARGET})
if(HOST_ARCH MATCHES "i[2-6]86")
set(HOST_ARCH X86)
elseif(HOST_ARCH STREQUAL "x86")
set(HOST_ARCH X86)
elseif(HOST_ARCH STREQUAL "amd64")
set(HOST_ARCH X86)
elseif(HOST_ARCH STREQUAL "x86_64")
set(HOST_ARCH X86)
elseif(HOST_ARCH MATCHES "sparc")
set(HOST_ARCH Sparc)
elseif(HOST_ARCH MATCHES "powerpc")
set(HOST_ARCH PowerPC)
elseif(HOST_ARCH MATCHES "alpha")
set(HOST_ARCH Alpha)
elseif(HOST_ARCH MATCHES "arm")
set(HOST_ARCH ARM)
elseif(HOST_ARCH MATCHES "mips")
set(HOST_ARCH Mips)
elseif(HOST_ARCH MATCHES "xcore")
set(HOST_ARCH XCore)
elseif(HOST_ARCH MATCHES "msp430")
set(HOST_ARCH MSP430)
else(HOST_ARCH MATCHES "i[2-6]86")
message(FATAL_ERROR "Unknown architecture ${HOST_ARCH}")
endif(HOST_ARCH MATCHES "i[2-6]86")
# Pass the list of LLVM targets as preprocessor constants.
foreach(TARGET ${HOST_ARCH} ${EXTRA_LLVM_MODULES})
set(LLVM_MODULES_DEFINE "${LLVM_MODULES_DEFINE} LLVM_TARGET(${TARGET})")
endforeach(TARGET)
set_source_files_properties(
${PROJECT_SOURCE_DIR}/driver/main.cpp PROPERTIES
COMPILE_DEFINITIONS LDC_TARGETS=${LLVM_MODULES_DEFINE}
)
# #
# Gather source files. # Gather source files.
# #
@ -270,6 +201,8 @@ add_definitions(
-DIN_LLVM -DIN_LLVM
-DOPAQUE_VTBLS -DOPAQUE_VTBLS
-DLDC_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}" -DLDC_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"
-DLDC_LLVM_VER=${LDC_LLVM_VER}
-DLDC_LLVM_VERSION_STRING="${LLVM_VERSION_STRING}"
) )
if(UNIX) if(UNIX)
@ -317,7 +250,7 @@ set_target_properties(
) )
# LDFLAGS should actually be in target property LINK_FLAGS, but this works, and gets around linking problems # LDFLAGS should actually be in target property LINK_FLAGS, but this works, and gets around linking problems
target_link_libraries(${LDC_LIB} "${LLVM_LDFLAGS} ${LLVM_LIBRARIES}") target_link_libraries(${LDC_LIB} "${LLVM_LDFLAGS}" ${LLVM_LIBRARIES})
if(WIN32) if(WIN32)
target_link_libraries(${LDC_LIB} imagehlp psapi) target_link_libraries(${LDC_LIB} imagehlp psapi)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@ -362,7 +295,7 @@ set_target_properties(${LDMD_EXE} PROPERTIES
# use symbols from libdl, ..., so LLVM_LDFLAGS must come _after_ them in the # use symbols from libdl, ..., so LLVM_LDFLAGS must come _after_ them in the
# command line. Maybe this could be improved using library groups, at least with # command line. Maybe this could be improved using library groups, at least with
# GNU ld. # GNU ld.
target_link_libraries(${LDMD_EXE} "${LLVM_LDFLAGS} ${LLVM_LIBRARIES} ${LLVM_LDFLAGS}") target_link_libraries(${LDMD_EXE} "${LLVM_LDFLAGS}" ${LLVM_LIBRARIES} "${LLVM_LDFLAGS}")
# #
# Install target. # Install target.

View file

@ -49,41 +49,48 @@ if (NOT LLVM_CONFIG)
endif() endif()
endif() endif()
else() else()
# llvm-config is written in Perl, thus we need to locate it first. macro(llvm_set var flag)
if(LLVM_FIND_QUIETLY) if(LLVM_FIND_QUIETLY)
set(_quiet_arg QUIET) set(_quiet_arg ERROR_QUIET)
endif()
find_package(Perl ${_quiet_arg})
if(NOT PERL_FOUND)
if (NOT FIND_LLVM_QUIETLY)
message(WARNING "Need Perl to execute llvm-config.")
endif() endif()
else() execute_process(
macro(llvm_set var flag) COMMAND ${LLVM_CONFIG} --${flag}
if(LLVM_FIND_QUIETLY) OUTPUT_VARIABLE LLVM_${var}
set(_quiet_arg ERROR_QUIET) OUTPUT_STRIP_TRAILING_WHITESPACE
endif() ${_quiet_arg}
execute_process( )
COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --${flag} ${LLVM_FIND_COMPONENTS} endmacro()
OUTPUT_VARIABLE LLVM_${var} macro(llvm_set_libs var flag prefix)
OUTPUT_STRIP_TRAILING_WHITESPACE ${_quiet_arg} if(LLVM_FIND_QUIETLY)
) set(_quiet_arg ERROR_QUIET)
endmacro() endif()
execute_process(
COMMAND ${LLVM_CONFIG} --${flag} ${LLVM_FIND_COMPONENTS}
OUTPUT_VARIABLE tmplibs
OUTPUT_STRIP_TRAILING_WHITESPACE
${_quiet_arg}
)
string(REGEX MATCHALL "${prefix}[^ ]+" LLVM_${var} ${tmplibs})
endmacro()
llvm_set(CXXFLAGS cxxflags) llvm_set(VERSION_STRING version)
llvm_set(HOST_TARGET host-target) if(${LLVM_VERSION_STRING} MATCHES "3.0[A-Za-z]*")
llvm_set(INCLUDE_DIRS includedir) # Version 3.0 does not support component all-targets
llvm_set(LDFLAGS ldflags) llvm_set(TARGETS_BUILT targets-built)
llvm_set(LIBRARIES libfiles) list(REMOVE_ITEM LLVM_FIND_COMPONENTS "all-targets" index)
llvm_set(LIBRARY_DIRS libdir) list(APPEND LLVM_FIND_COMPONENTS ${LLVM_TARGETS_BUILT})
llvm_set(ROOT_DIR prefix)
llvm_set(VERSION_STRING version)
endif() endif()
llvm_set(CXXFLAGS cxxflags)
llvm_set(HOST_TARGET host-target)
llvm_set(INCLUDE_DIRS includedir)
llvm_set(LDFLAGS ldflags)
llvm_set(LIBRARY_DIRS libdir)
llvm_set_libs(LIBRARIES libfiles "${LLVM_LIBRARY_DIRS}/")
llvm_set(ROOT_DIR prefix)
endif() endif()
string(REGEX REPLACE "([0-9]+).*" "\\1" LLVM_VERSION_MAJOR "${LLVM_VERSION_STRING}" ) string(REGEX REPLACE "([0-9]+).*" "\\1" LLVM_VERSION_MAJOR "${LLVM_VERSION_STRING}" )
string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" LLVM_VERSION_MINOR "${LLVM_VERSION_STRING}" ) string(REGEX REPLACE "[0-9]+\\.([0-9]+).*[A-Za-z]*" "\\1" LLVM_VERSION_MINOR "${LLVM_VERSION_STRING}" )
# Use the default CMake facilities for handling QUIET/REQUIRED. # Use the default CMake facilities for handling QUIET/REQUIRED.
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)

View file

@ -3,6 +3,7 @@
// some things are taken from llvm's llc tool // some things are taken from llvm's llc tool
// which uses the llvm license // which uses the llvm license
#include "gen/llvmcompat.h"
#include "gen/llvm.h" #include "gen/llvm.h"
#include "llvm/LinkAllVMCore.h" #include "llvm/LinkAllVMCore.h"
#include "llvm/Linker.h" #include "llvm/Linker.h"
@ -85,7 +86,7 @@ void printVersion() {
printf("D Language Documentation: http://d-programming-language.org/index.html\n" printf("D Language Documentation: http://d-programming-language.org/index.html\n"
"LDC Homepage: https://github.com/ldc-developers/ldc\n"); "LDC Homepage: https://github.com/ldc-developers/ldc\n");
printf("\n"); printf("\n");
printf(" Default target: %s\n", DEFAULT_TARGET_TRIPLE); printf(" Default target: %s\n", llvm::sys::getDefaultTargetTriple().c_str());
std::string CPU = llvm::sys::getHostCPUName(); std::string CPU = llvm::sys::getHostCPUName();
if (CPU == "generic") CPU = "(unknown)"; if (CPU == "generic") CPU = "(unknown)";
printf(" Host CPU: %s\n", CPU.c_str()); printf(" Host CPU: %s\n", CPU.c_str());
@ -219,14 +220,11 @@ int main(int argc, char** argv)
// Initialize LLVM. // Initialize LLVM.
// Initialize targets first, so that --version shows registered targets. // Initialize targets first, so that --version shows registered targets.
#define LLVM_TARGET(A) \ llvm::InitializeAllTargetInfos();
LLVMInitialize##A##TargetInfo(); \ llvm::InitializeAllTargets();
LLVMInitialize##A##Target(); \ llvm::InitializeAllTargetMCs();
LLVMInitialize##A##AsmPrinter(); \ llvm::InitializeAllAsmPrinters();
LLVMInitialize##A##AsmParser(); \ llvm::InitializeAllAsmParsers();
LLVMInitialize##A##TargetMC();
LDC_TARGETS
#undef LLVM_TARGET
// Handle fixed-up arguments! // Handle fixed-up arguments!
cl::SetVersionPrinter(&printVersion); cl::SetVersionPrinter(&printVersion);
@ -451,10 +449,22 @@ LDC_TARGETS
fatal(); fatal();
// override triple if needed // override triple if needed
const char* defaultTriple = DEFAULT_TARGET_TRIPLE; std::string defaultTriple = llvm::sys::getDefaultTargetTriple();
if ((sizeof(void*) == 4 && m64bits) || (sizeof(void*) == 8 && m32bits)) if (sizeof(void*) == 4 && m64bits)
{ {
defaultTriple = DEFAULT_ALT_TARGET_TRIPLE; #if LDC_LLVM_VER >= 301
defaultTriple = llvm::Triple(defaultTriple).get64BitArchVariant().str();
#else
defaultTriple = llvm::Triple__get64BitArchVariant(defaultTriple).str();
#endif
}
else if (sizeof(void*) == 8 && m32bits)
{
#if LDC_LLVM_VER >= 301
defaultTriple = llvm::Triple(defaultTriple).get32BitArchVariant().str();
#else
defaultTriple = llvm::Triple__get32BitArchVariant(defaultTriple).str();
#endif
} }
// did the user override the target triple? // did the user override the target triple?
@ -465,7 +475,7 @@ LDC_TARGETS
error("you must specify a target triple as well with -mtriple when using the -march option"); error("you must specify a target triple as well with -mtriple when using the -march option");
fatal(); fatal();
} }
global.params.targetTriple = defaultTriple; global.params.targetTriple = defaultTriple.c_str();
} }
else else
{ {
@ -603,79 +613,61 @@ LDC_TARGETS
// parse the OS out of the target triple // parse the OS out of the target triple
// see http://gcc.gnu.org/install/specific.html for details // see http://gcc.gnu.org/install/specific.html for details
// also llvm's different SubTargets have useful information // also llvm's different SubTargets have useful information
size_t npos = std::string::npos; switch (llvm::Triple(triple).getOS())
// windows
if (triple.find("win32") != npos)
{ {
global.params.os = OSWindows; case llvm::Triple::Win32:
VersionCondition::addPredefinedGlobalIdent("Windows"); global.params.os = OSWindows;
VersionCondition::addPredefinedGlobalIdent("Win32"); VersionCondition::addPredefinedGlobalIdent("Windows");
if (global.params.is64bit) { VersionCondition::addPredefinedGlobalIdent("Win32");
VersionCondition::addPredefinedGlobalIdent("Win64"); if (global.params.is64bit) {
} VersionCondition::addPredefinedGlobalIdent("Win64");
} }
// FIXME: mingw break;
else if (triple.find("mingw") != npos) case llvm::Triple::MinGW32:
{ global.params.os = OSWindows;
global.params.os = OSWindows; VersionCondition::addPredefinedGlobalIdent("Windows");
VersionCondition::addPredefinedGlobalIdent("Windows"); VersionCondition::addPredefinedGlobalIdent("Win32");
VersionCondition::addPredefinedGlobalIdent("Win32"); VersionCondition::addPredefinedGlobalIdent("mingw32");
VersionCondition::addPredefinedGlobalIdent("mingw32"); VersionCondition::addPredefinedGlobalIdent("MinGW");
VersionCondition::addPredefinedGlobalIdent("MinGW"); if (global.params.is64bit) {
if (global.params.is64bit) { VersionCondition::addPredefinedGlobalIdent("Win64");
VersionCondition::addPredefinedGlobalIdent("Win64"); }
} break;
} case llvm::Triple::Cygwin:
// FIXME: cygwin error("CygWin is not yet supported");
else if (triple.find("cygwin") != npos) fatal();
{ break;
error("CygWin is not yet supported"); case llvm::Triple::Linux:
fatal(); global.params.os = OSLinux;
} VersionCondition::addPredefinedGlobalIdent("linux");
// linux VersionCondition::addPredefinedGlobalIdent("Posix");
else if (triple.find("linux") != npos) break;
{ case llvm::Triple::Haiku:
global.params.os = OSLinux; global.params.os = OSHaiku;
VersionCondition::addPredefinedGlobalIdent("linux"); VersionCondition::addPredefinedGlobalIdent("Haiku");
VersionCondition::addPredefinedGlobalIdent("Posix"); VersionCondition::addPredefinedGlobalIdent("Posix");
} break;
// haiku case llvm::Triple::Darwin:
else if (triple.find("haiku") != npos) global.params.os = OSMacOSX;
{ VersionCondition::addPredefinedGlobalIdent("OSX");
global.params.os = OSHaiku; VersionCondition::addPredefinedGlobalIdent("darwin");
VersionCondition::addPredefinedGlobalIdent("Haiku"); VersionCondition::addPredefinedGlobalIdent("Posix");
VersionCondition::addPredefinedGlobalIdent("Posix"); break;
} case llvm::Triple::FreeBSD:
// darwin global.params.os = OSFreeBSD;
else if (triple.find("-darwin") != npos) VersionCondition::addPredefinedGlobalIdent("freebsd");
{ VersionCondition::addPredefinedGlobalIdent("FreeBSD");
global.params.os = OSMacOSX; VersionCondition::addPredefinedGlobalIdent("Posix");
VersionCondition::addPredefinedGlobalIdent("OSX"); break;
VersionCondition::addPredefinedGlobalIdent("darwin"); case llvm::Triple::Solaris:
VersionCondition::addPredefinedGlobalIdent("Posix"); global.params.os = OSSolaris;
} VersionCondition::addPredefinedGlobalIdent("solaris");
// freebsd VersionCondition::addPredefinedGlobalIdent("Solaris");
else if (triple.find("-freebsd") != npos) VersionCondition::addPredefinedGlobalIdent("Posix");
{ break;
global.params.os = OSFreeBSD; default:
VersionCondition::addPredefinedGlobalIdent("freebsd"); error("target '%s' is not yet supported", global.params.targetTriple);
VersionCondition::addPredefinedGlobalIdent("FreeBSD"); fatal();
VersionCondition::addPredefinedGlobalIdent("Posix");
}
// solaris
else if (triple.find("-solaris") != npos)
{
global.params.os = OSSolaris;
VersionCondition::addPredefinedGlobalIdent("solaris");
VersionCondition::addPredefinedGlobalIdent("Solaris");
VersionCondition::addPredefinedGlobalIdent("Posix");
}
// unsupported
else
{
error("target '%s' is not yet supported", global.params.targetTriple);
fatal();
} }
if (global.params.os == OSWindows) { if (global.params.os == OSWindows) {

83
gen/llvmcompat.cpp Normal file
View file

@ -0,0 +1,83 @@
#include "gen/llvmcompat.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/ADT/Triple.h"
#include <string>
#if LDC_LLVM_VER == 300
namespace llvm {
namespace sys {
std::string getDefaultTargetTriple() {
return LLVM_HOSTTRIPLE;
}
}
Triple Triple__get32BitArchVariant(const std::string& triple) {
Triple T(triple);
switch (T.getArch()) {
case Triple::UnknownArch:
case Triple::msp430:
T.setArch(Triple::UnknownArch);
break;
case Triple::amdil:
case Triple::arm:
case Triple::cellspu:
case Triple::le32:
case Triple::mblaze:
case Triple::mips:
case Triple::mipsel:
case Triple::ppc:
case Triple::sparc:
case Triple::tce:
case Triple::thumb:
case Triple::x86:
case Triple::xcore:
// Already 32-bit.
break;
case Triple::mips64: T.setArch(Triple::mips); break;
case Triple::mips64el: T.setArch(Triple::mipsel); break;
case Triple::ppc64: T.setArch(Triple::ppc); break;
case Triple::sparcv9: T.setArch(Triple::sparc); break;
case Triple::x86_64: T.setArch(Triple::x86); break;
}
return T;
}
Triple Triple__get64BitArchVariant(const std::string& triple) {
Triple T(triple);
switch (T.getArch()) {
case Triple::UnknownArch:
case Triple::amdil:
case Triple::arm:
case Triple::cellspu:
case Triple::le32:
case Triple::mblaze:
case Triple::msp430:
case Triple::tce:
case Triple::thumb:
case Triple::xcore:
T.setArch(Triple::UnknownArch);
break;
case Triple::mips64:
case Triple::mips64el:
case Triple::ppc64:
case Triple::sparcv9:
case Triple::x86_64:
// Already 64-bit.
break;
case Triple::mips: T.setArch(Triple::mips64); break;
case Triple::mipsel: T.setArch(Triple::mips64el); break;
case Triple::ppc: T.setArch(Triple::ppc64); break;
case Triple::sparc: T.setArch(Triple::sparcv9); break;
case Triple::x86: T.setArch(Triple::x86_64); break;
}
return T;
}
}
#endif

26
gen/llvmcompat.h Normal file
View file

@ -0,0 +1,26 @@
#ifdef _MSC_VER
#pragma once
#endif
#ifndef LDC_LLVMCOMPAT_H
#define LDC_LLVMCOMPAT_H
#include "llvm/ADT/Triple.h"
#include <string>
#if !defined(LDC_LLVM_VER)
#error "Please specify value for LDC_LLVM_VER."
#endif
#if LDC_LLVM_VER == 300
namespace llvm {
namespace sys {
std::string getDefaultTargetTriple();
}
Triple Triple__get32BitArchVariant(const std::string&_this);
Triple Triple__get64BitArchVariant(const std::string& _this);
}
#endif
#endif