Updated LLVM cmake detection

This commit is contained in:
Bartek Kryza
2022-08-03 23:45:51 +02:00
parent 487e5d435b
commit cc0119d079
4 changed files with 116 additions and 207 deletions

View File

@@ -1,89 +1,56 @@
cmake_minimum_required(VERSION 3.12)
#
# Project name
#
project(clang-uml)
#
# CMake standard defines
#
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_VERBOSE_MAKEFILE OFF)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
#
# clang-uml custom defines
#
set(CLANG_UML_INSTALL_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
set(CLANG_UML_INSTALL_BIN_DIR ${PROJECT_SOURCE_DIR}/bin)
set(UML_HEADERS_DIR ${PROJECT_SOURCE_DIR}/src/uml)
#
# CMake build options
#
option(LLVM_CONFIG_PATH "Path to custom llvm-config executable")
option(LINK_LLVM_SHARED "Should LLVM be linked using shared libraries or statically" ON)
option(GIT_VERSION "clang-uml version" "0.1.0")
if(LLVM_CONFIG_PATH)
#
# Setup LLVM
#
message(STATUS "Checking for LLVM and Clang...")
if(LLVM_PREFIX)
message(STATUS "Using llvm-config from ${LLVM_CONFIG_PATH}")
set(LIBCLANG_LLVM_CONFIG_EXECUTABLE ${LLVM_CONFIG_PATH})
set(LLVM_CONFIG_BINARY ${LLVM_CONFIG_PATH})
endif(LLVM_CONFIG_PATH)
endif(LLVM_PREFIX)
#set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
find_package(LLVM CONFIG REQUIRED)
message(STATUS "Checking for yaml-cpp...")
find_package(yaml-cpp REQUIRED)
message(STATUS "Checking for libclang...")
set(LLVM_PREFERRED_VERSION 14.0.0)
# Add
# -DLLVM_CONFIG_PATH=/path/to/llvm-config
# to use custom LLVM version
find_package(LibClang REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -std=c++17 ${LIBCLANG_CXXFLAGS}")
message(STATUS "Using CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
# Thirdparty sources
set(THIRDPARTY_HEADERS_DIR ${PROJECT_SOURCE_DIR}/thirdparty/)
find_package(LLVM REQUIRED CONFIG)
set(CLANG_INCLUDE_DIRS "llvm/clang/include")
set(CLANG_LIBS clang)
# Configure executable version
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/src/version)
configure_file(src/version.h.in ${PROJECT_BINARY_DIR}/src/version/version.h)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
execute_process(COMMAND gcc --print-file-name=include
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE GCC_STDDEF_INCLUDE)
message(STATUS "FOUND GCC STDDEF INCLUDE ${GCC_STDDEF_INCLUDE}")
include_directories(${GCC_STDDEF_INCLUDE})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${GCC_STDDEF_INCLUDE} -Wno-unused-parameter ")
endif()
find_package(LLVM REQUIRED CONFIG)
list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR})
include(AddLLVM)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})
message(STATUS "LLVM library dir: ${LLVM_LIBRARY_DIR}")
link_directories(${LLVM_LIBRARY_DIR})
include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${CLANG_UML_INSTALL_INCLUDE_DIR})
include_directories(${YAML_CPP_INCLUDE_DIR})
include_directories(${UML_HEADERS_DIR})
include_directories(${THIRDPARTY_HEADERS_DIR})
include_directories(${PROJECT_SOURCE_DIR}/src/)
include_directories(${PROJECT_BINARY_DIR}/src/version)
file(GLOB_RECURSE SOURCES src/*.cc include/*.h)
set(MAIN_SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc)
list(REMOVE_ITEM SOURCES ${MAIN_SOURCE_FILE})
set(LIBTOOLING_LIBS
if(LINK_LLVM_SHARED)
set(LIBTOOLING_LIBS clang-cpp LLVM)
else(LINK_LLVM_SHARED)
set(LIBTOOLING_LIBS
clangLex
clangFrontend
clangSerialization
@@ -108,14 +75,86 @@ set(LIBTOOLING_LIBS
LLVMObject
LLVMBitReader
LLVMCore
LLVMSupport
)
LLVMSupport)
endif(LINK_LLVM_SHARED)
#
# Setup threads library
#
find_package(Threads REQUIRED)
#
# Setup yaml-cpp
#
message(STATUS "Checking for yaml-cpp...")
find_package(yaml-cpp REQUIRED)
#message(STATUS "Checking for libclang...")
#set(LLVM_PREFERRED_VERSION 14.0.0)
# Add
# -DLLVM_CONFIG_PATH=/path/to/llvm-config
# to use custom LLVM version
#find_package(LibClang REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -std=c++17")
message(STATUS "Using CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
#
# Setup thirdparty sources
#
set(THIRDPARTY_HEADERS_DIR ${PROJECT_SOURCE_DIR}/thirdparty/)
#
# Configure clang-uml executable version
#
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/src/version)
configure_file(src/version.h.in ${PROJECT_BINARY_DIR}/src/version/version.h)
#
# Handle various compiler quirks
#
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
execute_process(COMMAND gcc --print-file-name=include
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE GCC_STDDEF_INCLUDE)
message(STATUS "FOUND GCC STDDEF INCLUDE ${GCC_STDDEF_INCLUDE}")
include_directories(${GCC_STDDEF_INCLUDE})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${GCC_STDDEF_INCLUDE} -Wno-unused-parameter")
endif()
#
# Setup include directories
#
include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${CLANG_UML_INSTALL_INCLUDE_DIR})
include_directories(${YAML_CPP_INCLUDE_DIR})
include_directories(${UML_HEADERS_DIR})
include_directories(${THIRDPARTY_HEADERS_DIR})
include_directories(${PROJECT_SOURCE_DIR}/src/)
include_directories(${PROJECT_BINARY_DIR}/src/version)
#
# Generate source list dynamically
#
file(GLOB_RECURSE SOURCES src/*.cc include/*.h)
set(MAIN_SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc)
list(REMOVE_ITEM SOURCES ${MAIN_SOURCE_FILE})
#
# Define library target for linking with test cases and output executable
#
add_library(clang-umllib OBJECT ${SOURCES})
#
# Define the target executable clang-uml
#
add_executable(clang-uml ${MAIN_SOURCE_FILE})
target_link_libraries(clang-uml
${LIBCLANG_LIBRARIES}
# ${LIBCLANG_LIBRARIES}
${YAML_CPP_LIBRARIES}
${LIBTOOLING_LIBS}
clang-umllib
@@ -123,12 +162,17 @@ target_link_libraries(clang-uml
target_compile_features(clang-uml PRIVATE cxx_std_17)
#
# Setup install options
#
include(GNUInstallDirs)
install(TARGETS clang-uml DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES LICENSE.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(FILES README.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
#
# Enable testing via CTest
#
enable_testing()
add_subdirectory(tests)

View File

@@ -1,139 +0,0 @@
# FindLibClang
#
# This module searches libclang and llvm-config, the llvm-config tool is used to
# get information about the installed llvm/clang package to compile LLVM based
# programs.
#
# It defines the following variables
#
# ``LIBCLANG_LLVM_CONFIG_EXECUTABLE``
# the llvm-config tool to get various information.
# ``LIBCLANG_LIBRARIES``
# the clang libraries to link against to use Clang/LLVM.
# ``LIBCLANG_LIBDIR``
# the directory where the clang libraries are located.
# ``LIBCLANG_FOUND``
# true if libclang was found
# ``LIBCLANG_VERSION_STRING``
# version number as a string
# ``LIBCLANG_CXXFLAGS``
# the compiler flags for files that include LLVM headers
#
#=============================================================================
# Copyright (C) 2011, 2012, 2013 Jan Erik Hanssen and Anders Bakken
# Copyright (C) 2015 Christian Schwarzgruber <c.schwarzgruber.cs@gmail.com>
#
# This file is part of RTags (https://github.com/Andersbakken/rtags).
#
# RTags is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RTags is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with RTags. If not, see <https://www.gnu.org/licenses/>.
if (NOT LIBCLANG_ROOT_DIR)
set(LIBCLANG_ROOT_DIR $ENV{LIBCLANG_ROOT_DIR})
endif ()
if (NOT LIBCLANG_LLVM_CONFIG_EXECUTABLE)
set(LIBCLANG_LLVM_CONFIG_EXECUTABLE $ENV{LIBCLANG_LLVM_CONFIG_EXECUTABLE})
if (NOT LIBCLANG_LLVM_CONFIG_EXECUTABLE)
find_program(LIBCLANG_LLVM_CONFIG_EXECUTABLE "llvm-config")
endif ()
if (NOT LIBCLANG_LLVM_CONFIG_EXECUTABLE)
if (APPLE)
execute_process(COMMAND brew --prefix llvm OUTPUT_VARIABLE BREW_LLVM_PATH RESULT_VARIABLE BREW_LLVM_RESULT)
if (NOT ${BREW_LLVM_RESULT} EQUAL 0)
set(BREW_LLVM_PATH "/usr/local/opt/llvm")
endif ()
string(STRIP ${BREW_LLVM_PATH} BREW_LLVM_PATH)
find_program(LIBCLANG_LLVM_CONFIG_EXECUTABLE NAMES llvm-config PATHS "${BREW_LLVM_PATH}/bin")
else ()
set(llvm_config_names llvm-config)
foreach(major RANGE 15 3)
list(APPEND llvm_config_names "llvm-config${major}" "llvm-config-${major}")
foreach(minor RANGE 9 0)
list(APPEND llvm_config_names "llvm-config${major}${minor}" "llvm-config-${major}.${minor}" "llvm-config-mp-${major}.${minor}")
endforeach ()
endforeach ()
find_program(LIBCLANG_LLVM_CONFIG_EXECUTABLE NAMES ${llvm_config_names} PATHS /usr/bin)
endif ()
endif ()
if (LIBCLANG_LLVM_CONFIG_EXECUTABLE)
message(STATUS "llvm-config executable found: ${LIBCLANG_LLVM_CONFIG_EXECUTABLE}")
endif ()
endif ()
if (NOT LIBCLANG_CXXFLAGS)
if (NOT LIBCLANG_LLVM_CONFIG_EXECUTABLE)
message(FATAL_ERROR "Could NOT find llvm-config executable and LIBCLANG_CXXFLAGS is not set ")
endif ()
execute_process(COMMAND ${LIBCLANG_LLVM_CONFIG_EXECUTABLE} --cxxflags OUTPUT_VARIABLE LIBCLANG_CXXFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
if (NOT LIBCLANG_CXXFLAGS)
find_path(LIBCLANG_CXXFLAGS_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT clang-c/Index.h HINTS ${LIBCLANG_ROOT_DIR}/include NO_DEFAULT_PATH)
if (NOT EXISTS ${LIBCLANG_CXXFLAGS_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT})
find_path(LIBCLANG_CXXFLAGS clang-c/Index.h)
if (NOT EXISTS ${LIBCLANG_CXXFLAGS})
message(FATAL_ERROR "Could NOT find clang include path. You can fix this by setting LIBCLANG_CXXFLAGS in your shell or as a cmake variable.")
endif ()
else ()
set(LIBCLANG_CXXFLAGS ${LIBCLANG_CXXFLAGS_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT})
endif ()
set(LIBCLANG_CXXFLAGS "-I${LIBCLANG_CXXFLAGS}")
endif ()
string(REGEX MATCHALL "-(D__?[a-zA-Z_]*|I([^\" ]+|\"[^\"]+\"))" LIBCLANG_CXXFLAGS "${LIBCLANG_CXXFLAGS}")
string(REGEX REPLACE ";" " " LIBCLANG_CXXFLAGS "${LIBCLANG_CXXFLAGS}")
set(LIBCLANG_CXXFLAGS ${LIBCLANG_CXXFLAGS} CACHE STRING "The LLVM C++ compiler flags needed to compile LLVM based applications.")
unset(LIBCLANG_CXXFLAGS_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT CACHE)
endif ()
if (NOT EXISTS ${LIBCLANG_LIBDIR})
if (NOT LIBCLANG_LLVM_CONFIG_EXECUTABLE)
message(FATAL_ERROR "Could NOT find llvm-config executable and LIBCLANG_LIBDIR is not set ")
endif ()
execute_process(COMMAND ${LIBCLANG_LLVM_CONFIG_EXECUTABLE} --libdir OUTPUT_VARIABLE LIBCLANG_LIBDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
if (NOT EXISTS ${LIBCLANG_LIBDIR})
message(FATAL_ERROR "Could NOT find clang libdir. You can fix this by setting LIBCLANG_LIBDIR in your shell or as a cmake variable.")
endif ()
set(LIBCLANG_LIBDIR ${LIBCLANG_LIBDIR} CACHE STRING "Path to the clang library.")
endif ()
if (NOT LIBCLANG_LIBRARIES)
find_library(LIBCLANG_LIB_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT NAMES clang libclang HINTS ${LIBCLANG_LIBDIR} ${LIBCLANG_ROOT_DIR}/lib NO_DEFAULT_PATH)
if (LIBCLANG_LIB_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT)
set(LIBCLANG_LIBRARIES "${LIBCLANG_LIB_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT}")
else ()
find_library(LIBCLANG_LIBRARIES NAMES clang libclang)
if (NOT EXISTS ${LIBCLANG_LIBRARIES})
set (LIBCLANG_LIBRARIES "-L${LIBCLANG_LIBDIR}" "-lclang" "-Wl,-rpath,${LIBCLANG_LIBDIR}")
endif ()
endif ()
unset(LIBCLANG_LIB_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT CACHE)
endif ()
set(LIBCLANG_LIBRARY ${LIBCLANG_LIBRARIES} CACHE FILEPATH "Path to the libclang library")
if (NOT LIBCLANG_SYSTEM_LIBS)
execute_process(COMMAND ${LIBCLANG_LLVM_CONFIG_EXECUTABLE} --system-libs OUTPUT_VARIABLE LIBCLANG_SYSTEM_LIBS OUTPUT_STRIP_TRAILING_WHITESPACE)
if (LIBCLANG_SYSTEM_LIBS)
set (LIBCLANG_LIBRARIES ${LIBCLANG_LIBRARIES} ${LIBCLANG_SYSTEM_LIBS})
endif ()
endif ()
if (LIBCLANG_LLVM_CONFIG_EXECUTABLE)
execute_process(COMMAND ${LIBCLANG_LLVM_CONFIG_EXECUTABLE} --version OUTPUT_VARIABLE LIBCLANG_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE)
else ()
set(LIBCLANG_VERSION_STRING "Unknown")
endif ()
message("-- Using Clang version ${LIBCLANG_VERSION_STRING} from ${LIBCLANG_LIBDIR} with CXXFLAGS ${LIBCLANG_CXXFLAGS}")
# Handly the QUIETLY and REQUIRED arguments and set LIBCLANG_FOUND to TRUE if all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibClang DEFAULT_MSG LIBCLANG_LIBRARY LIBCLANG_CXXFLAGS LIBCLANG_LIBDIR)
mark_as_advanced(LIBCLANG_CXXFLAGS LIBCLANG_LIBRARY LIBCLANG_LLVM_CONFIG_EXECUTABLE LIBCLANG_LIBDIR)

View File

@@ -24,6 +24,8 @@
#include "util/util.h"
#include "version.h"
#include <clang/Basic/Version.h>
#include <clang/Config/config.h>
#include <cli11/CLI11.hpp>
#include <spdlog/spdlog.h>
@@ -244,8 +246,10 @@ void print_version()
std::cout << "clang-uml " << clanguml::version::CLANG_UML_VERSION << '\n';
std::cout << "Copyright (C) 2021-2022 Bartek Kryza <bkryza@gmail.com>"
<< '\n';
std::cout << "Built with libclang: "
<< clanguml::version::CLANG_UML_LIBCLANG_VERSION << std::endl;
std::cout << "Built with LLVM version: "
<< std::string{BACKEND_PACKAGE_STRING}.substr(5) << std::endl;
std::cout << "Using LLVM version: " << clang::getClangFullVersion()
<< std::endl;
}
void print_diagrams_list(const clanguml::config::config &cfg)

View File

@@ -16,7 +16,7 @@ set(CLANG_UML_TEST_LIBRARIES
clang-umllib
${YAML_CPP_LIBRARIES}
${LIBTOOLING_LIBS}
${LIBCLANG_LIBRARIES}
# ${LIBCLANG_LIBRARIES}
Threads::Threads)