Try to make C++ header path determination a bit more robust.
Generate C++ include paths at compile time, fallback to absolute path of compiler cling was built with, and finally relative/PATH invocation. Previously if cling was built with wrapper to a compiler like ccache, then there was a good chance the wrapper would be invoked to find C++ headers, meaning it would fail unless the user also had said wrapper. This commit also: Changes LLVM_CXX macro to CLING_CXX_PATH. Fixes cling-compiledata.h not being updated after changes to cling-compiledata.h.in have occurred. Signed-off-by: Vassil Vassilev <vvasilev@cern.ch>
This commit is contained in:
parent
6ae88ce8e9
commit
b8b4becaf6
@ -139,7 +139,7 @@ $(call stripsrc,$(CLINGDIR)/%.o): $(CLINGDIR)/%.cpp $(LLVMDEP)
|
||||
|
||||
$(CLINGCOMPDH): FORCE $(LLVMDEP)
|
||||
@mkdir -p $(dir $@)
|
||||
@echo '#define LLVM_CXX "$(CXX) $(OPT) $(CLINGCXXFLAGSNOI)"' > $@_tmp
|
||||
@echo '#define CLING_CXX_PATH "$(CXX) $(OPT) $(CLINGCXXFLAGSNOI)"' > $@_tmp
|
||||
@diff -q $@_tmp $@ > /dev/null 2>&1 || mv $@_tmp $@
|
||||
@rm -f $@_tmp
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "ClingUtils.h"
|
||||
|
||||
#include "DeclCollector.h"
|
||||
#include "cling-compiledata.h"
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
@ -43,8 +42,9 @@
|
||||
#include <memory>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# include <unistd.h>
|
||||
# define getcwd_func getcwd
|
||||
#include "cling-compiledata.h"
|
||||
#include <unistd.h>
|
||||
#define getcwd_func getcwd
|
||||
#endif
|
||||
|
||||
// FIXME: This code has been taken (copied from) llvm/tools/clang/lib/Driver/WindowsToolChain.cpp
|
||||
@ -587,6 +587,29 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
static bool AddCxxPaths(llvm::StringRef PathStr, AdditionalArgList& Args) {
|
||||
bool Success = true;
|
||||
llvm::SmallVector<llvm::StringRef, 6> Paths;
|
||||
for (std::pair<llvm::StringRef, llvm::StringRef> Split
|
||||
= PathStr.split(':');
|
||||
!Split.second.empty(); Split = PathStr.split(':')) {
|
||||
if (!llvm::sys::fs::is_directory(Split.first)) {
|
||||
Success = false;
|
||||
break;
|
||||
}
|
||||
Paths.push_back(Split.first);
|
||||
PathStr = Split.second;
|
||||
}
|
||||
// Add remaining part
|
||||
if (Success && llvm::sys::fs::is_directory(PathStr)) {
|
||||
for (llvm::StringRef Path : Paths)
|
||||
Args.addArgument("-I", Path.str());
|
||||
Args.addArgument("-I", PathStr.str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
///\brief Adds standard library -I used by whatever compiler is found in PATH.
|
||||
@ -664,8 +687,21 @@ namespace {
|
||||
}
|
||||
#endif // _LIBCPP_VERSION
|
||||
|
||||
// first try the include directory cling was built with
|
||||
#ifdef CLING_CXX_INCL
|
||||
if (sArguments.empty())
|
||||
ReadCompilerIncludePaths(LLVM_CXX, buffer, sArguments);
|
||||
AddCxxPaths(CLING_CXX_INCL, sArguments);
|
||||
#endif
|
||||
// Then try the absolute path i.e.: '/usr/bin/g++'
|
||||
#ifdef CLING_CXX_PATH
|
||||
if (sArguments.empty())
|
||||
ReadCompilerIncludePaths(CLING_CXX_PATH, buffer, sArguments);
|
||||
#endif
|
||||
// Finally try the relative path 'g++'
|
||||
#ifdef CLING_CXX_RLTV
|
||||
if (sArguments.empty())
|
||||
ReadCompilerIncludePaths(CLING_CXX_RLTV, buffer, sArguments);
|
||||
#endif
|
||||
|
||||
if (sArguments.empty()) {
|
||||
// buffer is a copy of the query string that failed
|
||||
|
@ -108,27 +108,181 @@ endif()
|
||||
#add_dependencies(clangDriver ClangAttrList ClangDiagnosticDriver
|
||||
# ClangDriverOptions ClangCC1Options ClangCC1AsOptions)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h)
|
||||
if (UNIX)
|
||||
|
||||
add_file_dependencies(${CMAKE_CURRENT_SOURCE_DIR}/CIFactory.cpp ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h)
|
||||
add_file_dependencies(${CMAKE_CURRENT_SOURCE_DIR}/Interpreter.cpp ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h)
|
||||
# Remove all -I from CMAKE_CXX_FLAGS
|
||||
string(REPLACE ";" " " __flags "${CMAKE_CXX_FLAGS}")
|
||||
string(REGEX REPLACE "-I[^ ]+" "" CLING_COMPILER_FLAGS_NO_I "${__flags}")
|
||||
|
||||
# Remove all -I from CMAKE_CXX_FLAGS
|
||||
string(REPLACE ";" " " __flags "${CMAKE_CXX_FLAGS}")
|
||||
string(REGEX REPLACE "-I[^ ]+" "" CMAKE_CXX_FLAGS_NO_I "${__flags}")
|
||||
option(CLING_CXX_PATH "Compiler cling will invoke for c++ headers." "")
|
||||
option(CLING_CXX_HEADERS "Path cling will use for c++ headers." "")
|
||||
|
||||
# Remove absolute path from CMAKE_CXX_COMPILER
|
||||
get_filename_component(_path ${CMAKE_CXX_COMPILER} PATH)
|
||||
get_filename_component(_name ${CMAKE_CXX_COMPILER} NAME)
|
||||
if("$ENV{PATH}" MATCHES ${_path})
|
||||
set(CMAKE_CXX_COMPILER_RELATIVE ${_name})
|
||||
else()
|
||||
set(CMAKE_CXX_COMPILER_RELATIVE ${CMAKE_CXX_COMPILER})
|
||||
endif()
|
||||
function(stripNewLine strVal varName)
|
||||
string(STRIP "${strVal}" strVal)
|
||||
string(REGEX REPLACE "\\n$" "" strVal "${strVal}")
|
||||
SET(${varName} ${strVal} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
|
||||
"#define LLVM_CXX \"${CMAKE_CXX_COMPILER_RELATIVE} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
|
||||
"
|
||||
)
|
||||
if(NOT CLING_CXX_PATH)
|
||||
# Remove absolute path from CMAKE_CXX_COMPILER
|
||||
get_filename_component(_name ${CMAKE_CXX_COMPILER} NAME)
|
||||
get_filename_component(_path ${CMAKE_CXX_COMPILER} PATH)
|
||||
|
||||
# This should probably be more general...but how?
|
||||
if(_name STREQUAL "ccache" OR _name STREQUAL "distcc")
|
||||
separate_arguments(_arg_list UNIX_COMMAND "${CMAKE_CXX_COMPILER_ARG1}")
|
||||
if (_arg_list)
|
||||
list(GET _arg_list 0 _name)
|
||||
string(STRIP "${_name}" _name)
|
||||
if (APPLE)
|
||||
execute_process(COMMAND xcrun -f ${_name}
|
||||
OUTPUT_VARIABLE CLING_CXX_FOUND
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
stripNewLine("${CLING_CXX_FOUND}" CLING_CXX_FOUND)
|
||||
else()
|
||||
find_program(_cling_cxx_path "${_name}")
|
||||
execute_process(COMMAND ${_cling_cxx_path} -xc++ -E -v /dev/null
|
||||
OUTPUT_QUIET ERROR_VARIABLE _cling_cxx_path)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
execute_process(
|
||||
COMMAND echo ${_cling_cxx_path}
|
||||
COMMAND grep "COLLECT_GCC="
|
||||
OUTPUT_VARIABLE _cling_cxx_path)
|
||||
string(REPLACE "COLLECT_GCC=" "" _cling_cxx_path "${_cling_cxx_path}")
|
||||
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
execute_process(
|
||||
COMMAND echo ${_cling_cxx_path}
|
||||
COMMAND grep "/${_name}\" -cc1"
|
||||
OUTPUT_VARIABLE _cling_clng_path)
|
||||
|
||||
if(NOT _cling_clng_path)
|
||||
execute_process(
|
||||
COMMAND echo ${_cling_cxx_path}
|
||||
COMMAND grep "/clang\" -cc1"
|
||||
OUTPUT_VARIABLE _cling_clng_path)
|
||||
endif()
|
||||
|
||||
separate_arguments(_arg_list UNIX_COMMAND "${_cling_clng_path}")
|
||||
if (_arg_list)
|
||||
list(GET _arg_list 0 _cling_cxx_path)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
stripNewLine("${_cling_cxx_path}" _cling_cxx_path)
|
||||
set(CLING_CXX_FOUND "${_cling_cxx_path}")
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS "${CLING_CXX_FOUND}")
|
||||
find_program(CLING_CXX_FOUND "${_name}")
|
||||
endif()
|
||||
else()
|
||||
set(CLING_CXX_FOUND "")
|
||||
set(_name "")
|
||||
endif()
|
||||
|
||||
if (EXISTS ${CLING_CXX_FOUND})
|
||||
set(CLING_CXX_PATH ${CLING_CXX_FOUND})
|
||||
get_filename_component(_name ${CLING_CXX_PATH} NAME)
|
||||
get_filename_component(_path ${CLING_CXX_PATH} PATH)
|
||||
else()
|
||||
set(CLING_CXX_PATH "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}")
|
||||
if(_name)
|
||||
set(CLING_CXX_RLTV "${_name}")
|
||||
endif()
|
||||
set(_path "__THISREALLYBETTERNOTBEINPATH_THANKS__")
|
||||
endif()
|
||||
else()
|
||||
get_filename_component(_path ${CMAKE_CXX_COMPILER} PATH)
|
||||
endif()
|
||||
|
||||
if("$ENV{PATH}" MATCHES ${_path})
|
||||
set(CLING_CXX_RLTV ${_name})
|
||||
elseif(NOT CLING_CXX_PATH)
|
||||
set(CLING_CXX_PATH ${CMAKE_CXX_COMPILER})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CLING_CXX_HEADERS)
|
||||
if (CLING_CXX_PATH)
|
||||
execute_process(COMMAND ${CLING_CXX_PATH} -xc++ -E -v /dev/null
|
||||
OUTPUT_QUIET ERROR_VARIABLE CLING_CXX_HEADERS)
|
||||
else()
|
||||
execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -xc++ -E -v /dev/null
|
||||
OUTPUT_QUIET ERROR_VARIABLE CLING_CXX_HEADERS)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND echo ${CLING_CXX_HEADERS}
|
||||
COMMAND awk "/^#include </,/^End of search/{if (!/^#include </ && !/^End of search/){ print }}"
|
||||
COMMAND grep -E "(c|g)\\+\\+"
|
||||
OUTPUT_VARIABLE CLING_CXX_HEADERS)
|
||||
|
||||
stripNewLine("${CLING_CXX_HEADERS}" CLING_CXX_HEADERS)
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS ${CLING_CXX_HEADERS})
|
||||
string(REPLACE "\n" ";" _cxx_inc_paths ${CLING_CXX_HEADERS})
|
||||
foreach(_cxx_inc_path ${_cxx_inc_paths})
|
||||
string(STRIP "${_cxx_inc_path}" _cxx_inc_path)
|
||||
if (NOT EXISTS ${_cxx_inc_path})
|
||||
set(_cxx_inc_join "")
|
||||
break()
|
||||
endif()
|
||||
if(_cxx_inc_join)
|
||||
set(_cxx_inc_join "${_cxx_inc_join}:${_cxx_inc_path}")
|
||||
else()
|
||||
set(_cxx_inc_join "${_cxx_inc_path}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(CLING_CXX_HEADERS "${_cxx_inc_join}")
|
||||
if (NOT CLING_CXX_HEADERS)
|
||||
MESSAGE(WARNING "Cannot determine location of C++ headers for runtime.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
MESSAGE(STATUS "Cling will look for C++ headers in '${CLING_CXX_HEADERS}' at runtime.")
|
||||
|
||||
if (CLING_CXX_PATH)
|
||||
MESSAGE(STATUS "And if not found, will invoke: '${CLING_CXX_PATH}' for them.")
|
||||
if (CLING_CXX_RLTV)
|
||||
MESSAGE(STATUS "And then fallback to: '${CLING_CXX_RLTV}'")
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
|
||||
"
|
||||
#define CLING_CXX_INCL \"${CLING_CXX_HEADERS}\"
|
||||
#define CLING_CXX_PATH \"${CLING_CXX_PATH} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
|
||||
#define CLING_CXX_RLTV \"${CLING_CXX_RLTV} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
|
||||
")
|
||||
else()
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
|
||||
"
|
||||
#define CLING_CXX_INCL \"${CLING_CXX_HEADERS}\"
|
||||
#define CLING_CXX_PATH \"${CLING_CXX_PATH} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
|
||||
")
|
||||
endif()
|
||||
else()
|
||||
MESSAGE(STATUS "And if not found, will invoke: '${CLING_CXX_RLTV}' for them.")
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
|
||||
"
|
||||
#define CLING_CXX_INCL \"${CLING_CXX_HEADERS}\"
|
||||
#define CLING_CXX_RLTV \"${CLING_CXX_RLTV} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
|
||||
")
|
||||
endif()
|
||||
|
||||
# Make sure this goes last so so we can pick up any changes that occured
|
||||
# Also means cling-compiledata.h.in should be edited never cling-compiledata.h
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h
|
||||
MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
|
||||
COMMENT "Updating cling-compiledata.h")
|
||||
|
||||
add_file_dependencies(${CMAKE_CURRENT_SOURCE_DIR}/CIFactory.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h)
|
||||
add_file_dependencies(${CMAKE_CURRENT_SOURCE_DIR}/Interpreter.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h)
|
||||
|
||||
endif() # UNIX
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "cling/Interpreter/Interpreter.h"
|
||||
#include "ClingUtils.h"
|
||||
|
||||
#include "cling-compiledata.h"
|
||||
#include "DynamicLookup.h"
|
||||
#include "ExternalInterpreterSource.h"
|
||||
#include "ForwardDeclPrinter.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user