diff --git a/CMakeLists.txt b/CMakeLists.txt index eafe936b..9444c745 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,18 +1,19 @@ project(ldc) - cmake_minimum_required(VERSION 2.6) -# actually, 2.4 will work, with a warning -# if we required 2.4, 2.6+ would switch to a compatibility mode and cause problems on 2.6+ specifics -# LLVM-CONFIG is written in perl, for this reason we need to know here is perl -include(FindPerl) -if(NOT PERL) - message(FATAL_ERROR "perl not found") -endif(NOT PERL) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules") + +set(EXTRA_LLVM_MODULES "" CACHE STRING + "Extra LLVM components to link in (see llvm-config --components)") +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 2.9 EXACT REQUIRED + bitwriter linker ipo instrumentation backend ${EXTRA_LLVM_MODULES}) + +set(LLVM_CONFIG_HEADER "config.h" CACHE STRING "Filename of llvm config header fequently see: config.h, config-32.h, config-64.h") -#################### -# LLVM -#################### include(FindPkgConfig) if(NOT PKG_CONFIG_FOUND) message(FATAL_ERROR "pkg-config not found") @@ -28,37 +29,6 @@ else(NOT PKG_CONFIG_FOUND) endif(NOT LIBCONFIGPP_FOUND) endif(NOT PKG_CONFIG_FOUND) -find_program(LLVM_CONFIG llvm-config ${LLVM_INSTDIR}/bin DOC "path to llvm-config tool") -# get llvm's install dir. a little hackish, we could do something like llvm-config --prefix, but this does as well -string(REPLACE "/bin/llvm-config" "" LLVM_DIR ${LLVM_CONFIG}) - -set(LLVM_INSTDIR ${LLVM_DIR} CACHE PATH "LLVM installation directory" FORCE) -set(LLVM_CONFIG_HEADER "config.h" CACHE STRING "Filename of llvm config header fequently see: config.h, config-32.h, config-64.h") -if(NOT LLVM_INSTDIR) - message(FATAL_ERROR "llvm not found") -endif(NOT LLVM_INSTDIR) - -execute_process( - COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --host-target - OUTPUT_VARIABLE HOST_TARGET - OUTPUT_STRIP_TRAILING_WHITESPACE -) -execute_process( - COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --cxxflags - OUTPUT_VARIABLE LLVM_CXXFLAGS - OUTPUT_STRIP_TRAILING_WHITESPACE -) -execute_process( - COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --ldflags - OUTPUT_VARIABLE LLVM_LDFLAGS - OUTPUT_STRIP_TRAILING_WHITESPACE -) -execute_process( - COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --includedir - OUTPUT_VARIABLE LLVM_INCLUDEDIR - OUTPUT_STRIP_TRAILING_WHITESPACE -) - #################### # LDC #################### @@ -151,31 +121,23 @@ set(LDC_GENERATED ) ########## idgen and impcnvgen done -include_directories(. ${DMDFE_PATH} ${DMDFE_PATH}/root ${PROJECT_BINARY_DIR}/${DMDFE_PATH} ${PROJECT_SOURCE_DIR} ${LLVM_INCLUDEDIR}) - -set(EXTRA_LLVM_MODULES "" CACHE STRING "extra llvm components to link in (see llvm-config --components)") -separate_arguments(EXTRA_LLVM_MODULES) -execute_process( - COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --libfiles bitwriter linker ipo instrumentation backend ${EXTRA_LLVM_MODULES} - OUTPUT_VARIABLE LLVM_LIBS - OUTPUT_STRIP_TRAILING_WHITESPACE -) +include_directories(. ${DMDFE_PATH} ${DMDFE_PATH}/root ${PROJECT_BINARY_DIR}/${DMDFE_PATH} ${PROJECT_SOURCE_DIR} ${LLVM_INCLUDE_DIRS}) ########## # build a define that contains all LLVM targets required and is usable for # preprocessor code generation. start with the native target. -find_path(LLVM_CONFIG_FILE_PATH ${LLVM_CONFIG_HEADER} PATHS ${LLVM_INCLUDEDIR}/llvm/Config ${LLVM_INCLUDEDIR}/Config NO_DEFAULT_PATH) +find_file(LLVM_CONFIG_FILE_PATH ${LLVM_CONFIG_HEADER} PATHS ${LLVM_ROOT_DIR}/include/llvm/Config ${LLVM_INCLUDE_DIRS} NO_DEFAULT_PATH) if(LLVM_CONFIG_FILE_PATH STREQUAL "LLVM_CONFIG_FILE_PATH-NOTFOUND") - message("Couldn't find your llvm ${LLVM_CONFIG_HEADER} file in ${LLVM_INCLUDEDIR}, no native target will be initialized.") + message("Couldn't find your llvm ${LLVM_CONFIG_HEADER} file in ${LLVM_ROOT_DIR}, no native target will be initialized.") else(LLVM_CONFIG_FILE_PATH STREQUAL "LLVM_CONFIG_FILE_PATH-NOTFOUND") if(NOT HOST_TARGET AND NOT DEFAULT_TARGET) - file(STRINGS ${LLVM_CONFIG_FILE_PATH}/${LLVM_CONFIG_HEADER} LLVM_HOSTTRIPLE REGEX "^#define LLVM_HOSTTRIPLE") + file(STRINGS ${LLVM_CONFIG_FILE_PATH} LLVM_HOSTTRIPLE REGEX "^#define LLVM_HOSTTRIPLE") if(LLVM_HOSTTRIPLE) string(REGEX REPLACE "^#define LLVM_HOSTTRIPLE \"(.*)\"$" "\\1" HOST_TARGET ${LLVM_HOSTTRIPLE}) endif(LLVM_HOSTTRIPLE) endif(NOT HOST_TARGET AND NOT DEFAULT_TARGET) - file(STRINGS ${LLVM_CONFIG_FILE_PATH}/${LLVM_CONFIG_HEADER} LLVM_NATIVE_ARCH REGEX "^#define LLVM_NATIVE_ARCH") + file(STRINGS ${LLVM_CONFIG_FILE_PATH} LLVM_NATIVE_ARCH REGEX "^#define LLVM_NATIVE_ARCH") if(LLVM_NATIVE_ARCH) string(REGEX REPLACE "^#define LLVM_NATIVE_ARCH (.*)(Target|)$" "\\1" LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}) message(STATUS "Found native target ${LLVM_NATIVE_ARCH}") @@ -282,7 +244,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_EXE} "${LLVM_LDFLAGS} ${LLVM_LIBS}" ${LIBCONFIG_LDFLAGS} config++) +target_link_libraries(${LDC_EXE} "${LLVM_LDFLAGS} ${LLVM_LIBRARIES}" ${LIBCONFIG_LDFLAGS} config++) if(WIN32) target_link_libraries(${LDC_EXE} imagehlp psapi) elseif(UNIX) diff --git a/cmake/Modules/FindLLVM.cmake b/cmake/Modules/FindLLVM.cmake new file mode 100644 index 00000000..a4c04fdc --- /dev/null +++ b/cmake/Modules/FindLLVM.cmake @@ -0,0 +1,73 @@ +# - Find LLVM headers and libraries. +# This module locates LLVM and adapts the llvm-config output for use with +# CMake. +# +# A given list of COMPONENTS is passed to llvm-config. +# +# The following variables are defined: +# LLVM_FOUND - true if LLVM was found +# LLVM_CXXFLAGS - C++ compiler flags for files that include LLVM headers. +# LLVM_HOST_TARGET - Target triple used to configure LLVM. +# LLVM_INCLUDE_DIRS - Directory containing LLVM include files. +# LLVM_LDFLAGS - Linker flags to add when linking against LLVM +# (includes -LLLVM_LIBRARY_DIRS). +# LLVM_LIBRARIES - Full paths to the library files to link against. +# LLVM_LIBRARY_DIRS - Directory containing LLVM libraries. +# LLVM_ROOT_DIR - The root directory of the LLVM installation. +# llvm-config is searched for in ${LLVM_ROOT_DIR}/bin. +# LLVM_VERSION_MAJOR - Major version of LLVM. +# LLVM_VERSION_MINOR - Minor version of LLVM. +# LLVM_VERSION_STRING - Full LLVM version string (e.g. 2.9). +# +# Note: The variable names were chosen in conformance with the offical CMake +# guidelines, see ${CMAKE_ROOT}/Modules/readme.txt. + +find_program(LLVM_CONFIG llvm-config ${LLVM_ROOT_DIR}/bin + DOC "Path to llvm-config tool.") + +if (NOT LLVM_CONFIG) + if (NOT FIND_LLVM_QUIETLY) + message(WARNING "Could not find llvm-config. Consider manually setting LLVM_ROOT_DIR.") + 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} + OUTPUT_VARIABLE LLVM_${var} + OUTPUT_STRIP_TRAILING_WHITESPACE ${_quiet_arg} + ) + endmacro() + + 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(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}" ) + +# Use the default CMake facilities for handling QUIET/REQUIRED. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LLVM + REQUIRED_VARS LLVM_ROOT_DIR LLVM_HOST_TARGET + VERSION_VAR LLVM_VERSION_STRING)