diff --git a/makefiles/toolchain/llvm.inc.mk b/makefiles/toolchain/llvm.inc.mk index f58c0c5776..67b8bda407 100644 --- a/makefiles/toolchain/llvm.inc.mk +++ b/makefiles/toolchain/llvm.inc.mk @@ -32,72 +32,41 @@ export SIZE = $(LLVMPREFIX)size # We use GDB for debugging for now, maybe LLDB will be supported in the future. include $(RIOTMAKE)/tools/gdb.inc.mk -ifneq (,$(TARGET_ARCH)) - # Clang on Linux uses GCC's C++ headers and libstdc++ (installed with GCC) - # Ubuntu and Debian use /etc/alternatives/gcc-$(TARGET_ARCH)-include/c++/$(GCC_VERSION) - # Arch uses /usr/$(TARGET_ARCH)/include/c++/$(GCC_VERSION) - # Gentoo uses /usr/lib/gcc/$(TARGET_ARCH)/$(GCC_VERSION)/include/g++-v5 - GCC_CXX_INCLUDE_PATTERNS ?= \ - /etc/alternatives/gcc-$(TARGET_ARCH)-include/c++/*/ \ - /usr/$(TARGET_ARCH)/include/c++/*/ \ - /usr/lib/gcc/$(TARGET_ARCH)/*/include/g++-v8 \ - /usr/lib/gcc/$(TARGET_ARCH)/*/include/g++-v7 \ - /usr/lib/gcc/$(TARGET_ARCH)/*/include/g++-v6 \ - /usr/lib/gcc/$(TARGET_ARCH)/*/include/g++-v5 \ - # +# Include directories from gcc +# $1: language +# +# `realpath` is used instead of `abspath` to support Mingw32 which has issues +# with windows formatted gcc directories +# +# CFLAGS_CPU is used to get the correct multilib include header. +gcc_include_dirs = $(realpath \ + $(shell $(PREFIX)gcc $(CFLAGS_CPU) -v -x $1 -E /dev/null 2>&1 | \ + sed \ + -e '1,/\#include <...> search starts here:/d' \ + -e '/End of search list./,$$d' \ + -e 's/^ *//')\ +) - # Try to find the proper multilib directory using GCC, this may fail if a cross- - # GCC is not installed. - ifeq ($(GCC_MULTI_DIR),) - GCC_MULTI_DIR := $(shell $(PREFIX)gcc $(CFLAGS) -print-multi-directory 2>/dev/null) +ifneq (,$(TARGET_ARCH)) + ifeq (,$(CFLAGS_CPU)) + $(error CFLAGS_CPU must have been defined to use `llvm`.) endif # Tell clang to cross compile - export CFLAGS += -target $(TARGET_ARCH) - export CXXFLAGS += -target $(TARGET_ARCH) + CFLAGS += -target $(TARGET_ARCH) + CXXFLAGS += -target $(TARGET_ARCH) # We currently don't use LLVM for linking (see comment above). - #export LINKFLAGS += -target $(TARGET_ARCH) + # LINKFLAGS += -target $(TARGET_ARCH) - # Use the wildcard Makefile function to search for existing directories matching - # the patterns above. We use the -isystem gcc/clang argument to add the include - # directories as system include directories, which means they will not be - # searched until after all the project specific include directories (-I/path) - # We sort the list of found directories and take the last one, it will likely be - # the most recent GCC version. This avoids using old headers left over from - # previous tool chain installations. - GCC_CXX_INCLUDES ?= \ - $(addprefix \ - -isystem $(firstword \ - $(foreach pat, $(GCC_CXX_INCLUDE_PATTERNS), $(lastword $(sort $(wildcard $(pat)))))), \ - /. /$(TARGET_ARCH)/$(GCC_MULTI_DIR) /backward \ - ) + # Clang on Linux uses GCC's C and C++ headers and libstdc++ (installed with GCC) - # If nothing was found we will try to fall back to searching for a cross-gcc in - # the current PATH and use a relative path for the includes - ifeq (,$(GCC_CXX_INCLUDES)) - GCC_CXX_INCLUDES := $(addprefix -isystem ,$(wildcard $(dir $(shell which $(PREFIX)gcc))../$(TARGET_TRIPLE)/include)) - endif + # Extract include directories from GCC + GCC_C_INCLUDE_DIRS = $(call gcc_include_dirs,c) + GCC_CXX_INCLUDE_DIRS = $(call gcc_include_dirs,c++) - # Pass the includes to the C++ compilation rule in Makefile.base - export CXXINCLUDES += $(GCC_CXX_INCLUDES) + GCC_C_INCLUDES = $(addprefix -isystem ,$(GCC_C_INCLUDE_DIRS)) + GCC_CXX_INCLUDES = $(addprefix -isystem ,$(GCC_CXX_INCLUDE_DIRS)) - # Some C headers (e.g. limits.h) are located with the GCC libraries - GCC_C_INCLUDE_PATTERNS ?= \ - /usr/lib/gcc/$(TARGET_TRIPLE)/*/ \ - # - - GCC_C_INCLUDES ?= \ - $(addprefix -isystem ,$(wildcard $(addprefix \ - $(lastword $(sort \ - $(foreach pat, $(GCC_C_INCLUDE_PATTERNS), $(wildcard $(pat))))), \ - include include-fixed) \ - )) - - # If nothing was found we will try to fall back to searching for the libgcc used - # by an installed cross-GCC and use its headers. - ifeq (,$(GCC_C_INCLUDES)) - GCC_C_INCLUDES := $(addprefix -isystem ,$(wildcard $(addprefix $(dir $(shell $(PREFIX)gcc -print-libgcc-file-name)), include include-fixed))) - endif - - export INCLUDES += $(GCC_C_INCLUDES) + INCLUDES += $(GCC_C_INCLUDES) + CXXINCLUDES += $(GCC_CXX_INCLUDES) endif diff --git a/makefiles/vars.inc.mk b/makefiles/vars.inc.mk index 7fc732cd10..3492bffbf0 100644 --- a/makefiles/vars.inc.mk +++ b/makefiles/vars.inc.mk @@ -12,6 +12,7 @@ export CPU # The CPU, set by the board's Makefile.include. export CPU_MODEL # The specific identifier of the used CPU, used for some CPU implementations to differentiate between different memory layouts export MCU # The MCU, set by the board's Makefile.include, or defaulted to the same value as CPU. export INCLUDES # The extra include paths, set by the various Makefile.include files. +export CXXINCLUDES # The extra include paths for c++, set by the various Makefile.include files. export USEMODULE # Sys Module dependencies of the application. Set in the application's Makefile. export USEPKG # Pkg dependencies (third party modules) of the application. Set in the application's Makefile.