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:
committed by
sftnight
parent
6ae88ce8e9
commit
b8b4becaf6
@ -139,7 +139,7 @@ $(call stripsrc,$(CLINGDIR)/%.o): $(CLINGDIR)/%.cpp $(LLVMDEP)
|
|||||||
|
|
||||||
$(CLINGCOMPDH): FORCE $(LLVMDEP)
|
$(CLINGCOMPDH): FORCE $(LLVMDEP)
|
||||||
@mkdir -p $(dir $@)
|
@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 $@
|
@diff -q $@_tmp $@ > /dev/null 2>&1 || mv $@_tmp $@
|
||||||
@rm -f $@_tmp
|
@rm -f $@_tmp
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "ClingUtils.h"
|
#include "ClingUtils.h"
|
||||||
|
|
||||||
#include "DeclCollector.h"
|
#include "DeclCollector.h"
|
||||||
#include "cling-compiledata.h"
|
|
||||||
|
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
#include "clang/Basic/TargetInfo.h"
|
#include "clang/Basic/TargetInfo.h"
|
||||||
@ -43,8 +42,9 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
# include <unistd.h>
|
#include "cling-compiledata.h"
|
||||||
# define getcwd_func getcwd
|
#include <unistd.h>
|
||||||
|
#define getcwd_func getcwd
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: This code has been taken (copied from) llvm/tools/clang/lib/Driver/WindowsToolChain.cpp
|
// 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
|
#endif
|
||||||
|
|
||||||
///\brief Adds standard library -I used by whatever compiler is found in PATH.
|
///\brief Adds standard library -I used by whatever compiler is found in PATH.
|
||||||
@ -664,8 +687,21 @@ namespace {
|
|||||||
}
|
}
|
||||||
#endif // _LIBCPP_VERSION
|
#endif // _LIBCPP_VERSION
|
||||||
|
|
||||||
|
// first try the include directory cling was built with
|
||||||
|
#ifdef CLING_CXX_INCL
|
||||||
if (sArguments.empty())
|
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()) {
|
if (sArguments.empty()) {
|
||||||
// buffer is a copy of the query string that failed
|
// buffer is a copy of the query string that failed
|
||||||
|
@ -108,27 +108,181 @@ endif()
|
|||||||
#add_dependencies(clangDriver ClangAttrList ClangDiagnosticDriver
|
#add_dependencies(clangDriver ClangAttrList ClangDiagnosticDriver
|
||||||
# ClangDriverOptions ClangCC1Options ClangCC1AsOptions)
|
# ClangDriverOptions ClangCC1Options ClangCC1AsOptions)
|
||||||
|
|
||||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h
|
if (UNIX)
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h)
|
|
||||||
|
|
||||||
add_file_dependencies(${CMAKE_CURRENT_SOURCE_DIR}/CIFactory.cpp ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h)
|
# Remove all -I from CMAKE_CXX_FLAGS
|
||||||
add_file_dependencies(${CMAKE_CURRENT_SOURCE_DIR}/Interpreter.cpp ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h)
|
string(REPLACE ";" " " __flags "${CMAKE_CXX_FLAGS}")
|
||||||
|
string(REGEX REPLACE "-I[^ ]+" "" CLING_COMPILER_FLAGS_NO_I "${__flags}")
|
||||||
|
|
||||||
# Remove all -I from CMAKE_CXX_FLAGS
|
option(CLING_CXX_PATH "Compiler cling will invoke for c++ headers." "")
|
||||||
string(REPLACE ";" " " __flags "${CMAKE_CXX_FLAGS}")
|
option(CLING_CXX_HEADERS "Path cling will use for c++ headers." "")
|
||||||
string(REGEX REPLACE "-I[^ ]+" "" CMAKE_CXX_FLAGS_NO_I "${__flags}")
|
|
||||||
|
|
||||||
# Remove absolute path from CMAKE_CXX_COMPILER
|
function(stripNewLine strVal varName)
|
||||||
get_filename_component(_path ${CMAKE_CXX_COMPILER} PATH)
|
string(STRIP "${strVal}" strVal)
|
||||||
get_filename_component(_name ${CMAKE_CXX_COMPILER} NAME)
|
string(REGEX REPLACE "\\n$" "" strVal "${strVal}")
|
||||||
if("$ENV{PATH}" MATCHES ${_path})
|
SET(${varName} ${strVal} PARENT_SCOPE)
|
||||||
set(CMAKE_CXX_COMPILER_RELATIVE ${_name})
|
endfunction()
|
||||||
else()
|
|
||||||
set(CMAKE_CXX_COMPILER_RELATIVE ${CMAKE_CXX_COMPILER})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
|
if(NOT CLING_CXX_PATH)
|
||||||
"#define LLVM_CXX \"${CMAKE_CXX_COMPILER_RELATIVE} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
|
# 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 "cling/Interpreter/Interpreter.h"
|
||||||
#include "ClingUtils.h"
|
#include "ClingUtils.h"
|
||||||
|
|
||||||
#include "cling-compiledata.h"
|
|
||||||
#include "DynamicLookup.h"
|
#include "DynamicLookup.h"
|
||||||
#include "ExternalInterpreterSource.h"
|
#include "ExternalInterpreterSource.h"
|
||||||
#include "ForwardDeclPrinter.h"
|
#include "ForwardDeclPrinter.h"
|
||||||
|
Reference in New Issue
Block a user