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.
#
# 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
# work across LLVM »minor« releases.
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++.
@ -94,7 +87,7 @@ set_target_properties(
idgen impcnvgen PROPERTIES
LINKER_LANGUAGE CXX
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(IMPCNVGEN_LOC impcnvgen LOCATION)
@ -123,68 +116,6 @@ set(LDC_GENERATED
${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.
#
@ -270,6 +201,8 @@ add_definitions(
-DIN_LLVM
-DOPAQUE_VTBLS
-DLDC_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"
-DLDC_LLVM_VER=${LDC_LLVM_VER}
-DLDC_LLVM_VERSION_STRING="${LLVM_VERSION_STRING}"
)
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
target_link_libraries(${LDC_LIB} "${LLVM_LDFLAGS} ${LLVM_LIBRARIES}")
target_link_libraries(${LDC_LIB} "${LLVM_LDFLAGS}" ${LLVM_LIBRARIES})
if(WIN32)
target_link_libraries(${LDC_LIB} imagehlp psapi)
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
# command line. Maybe this could be improved using library groups, at least with
# 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.

View file

@ -49,41 +49,48 @@ if (NOT LLVM_CONFIG)
endif()
endif()
else()
# llvm-config is written in Perl, thus we need to locate it first.
if(LLVM_FIND_QUIETLY)
set(_quiet_arg 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()
else()
macro(llvm_set var flag)
if(LLVM_FIND_QUIETLY)
set(_quiet_arg ERROR_QUIET)
endif()
execute_process(
COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --${flag} ${LLVM_FIND_COMPONENTS}
COMMAND ${LLVM_CONFIG} --${flag}
OUTPUT_VARIABLE LLVM_${var}
OUTPUT_STRIP_TRAILING_WHITESPACE ${_quiet_arg}
OUTPUT_STRIP_TRAILING_WHITESPACE
${_quiet_arg}
)
endmacro()
macro(llvm_set_libs var flag prefix)
if(LLVM_FIND_QUIETLY)
set(_quiet_arg ERROR_QUIET)
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(VERSION_STRING version)
if(${LLVM_VERSION_STRING} MATCHES "3.0[A-Za-z]*")
# Version 3.0 does not support component all-targets
llvm_set(TARGETS_BUILT targets-built)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "all-targets" index)
list(APPEND LLVM_FIND_COMPONENTS ${LLVM_TARGETS_BUILT})
endif()
llvm_set(CXXFLAGS cxxflags)
llvm_set(HOST_TARGET host-target)
llvm_set(INCLUDE_DIRS includedir)
llvm_set(LDFLAGS ldflags)
llvm_set(LIBRARIES libfiles)
llvm_set(LIBRARY_DIRS libdir)
llvm_set_libs(LIBRARIES libfiles "${LLVM_LIBRARY_DIRS}/")
llvm_set(ROOT_DIR prefix)
llvm_set(VERSION_STRING version)
endif()
endif()
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.
include(FindPackageHandleStandardArgs)

View file

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

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