diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fb025d9abcc1..b4ff3f7870c60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -402,7 +402,8 @@ zephyr_ld_options( ) get_property(TOPT GLOBAL PROPERTY TOPT) -set_ifndef( TOPT -T) +set_ifndef( TOPT -Wl,-T) # clang doesn't pick -T for some reason and complains, + # while -Wl,-T works for both, gcc and clang if(NOT CONFIG_NATIVE_APPLICATION) # Funny thing is if this is set to =error, some architectures will diff --git a/arch/posix/CMakeLists.txt b/arch/posix/CMakeLists.txt index 35110ed44806e..ba208328b53a1 100644 --- a/arch/posix/CMakeLists.txt +++ b/arch/posix/CMakeLists.txt @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_compile_options( - -fno-freestanding -m32 -MMD -MP @@ -9,6 +8,9 @@ zephyr_compile_options( -include ${ZEPHYR_BASE}/arch/posix/include/posix_cheats.h ) +# @Intent: Obtain compiler specific flags for no freestanding compilation +toolchain_cc_no_freestanding_options() + zephyr_include_directories(${BOARD_DIR}) zephyr_compile_options_ifdef(CONFIG_COVERAGE diff --git a/boards/posix/native_posix/native_posix.yaml b/boards/posix/native_posix/native_posix.yaml index ff5fbc0ff234a..25bdb1c231fab 100644 --- a/boards/posix/native_posix/native_posix.yaml +++ b/boards/posix/native_posix/native_posix.yaml @@ -4,6 +4,7 @@ type: native arch: posix toolchain: - zephyr + - llvm supported: - netif:eth - usb_device diff --git a/cmake/compiler/clang/generic.cmake b/cmake/compiler/clang/generic.cmake index b5ea7833e1341..18e2b06e9072f 100644 --- a/cmake/compiler/clang/generic.cmake +++ b/cmake/compiler/clang/generic.cmake @@ -1,3 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 -find_program(CMAKE_C_COMPILER clang PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +if(DEFINED TOOLCHAIN_HOME) + set(find_program_clang_args PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +endif() + +find_program(CMAKE_C_COMPILER clang ${find_program_clang_args}) + diff --git a/cmake/compiler/clang/target.cmake b/cmake/compiler/clang/target.cmake index 545913c127a41..00bb8dd261839 100644 --- a/cmake/compiler/clang/target.cmake +++ b/cmake/compiler/clang/target.cmake @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -# Configuration for host installed llvm +# Configuration for host installed clang # set(NOSTDINC "") @@ -11,54 +11,80 @@ if(NOT DEFINED NOSYSDEF_CFLAG) set(NOSYSDEF_CFLAG -undef) endif() -find_program(CMAKE_C_COMPILER clang PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) -find_program(CMAKE_CXX_COMPILER clang++ PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) -find_program(CMAKE_AR llvm-ar PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) -find_program(CMAKE_LINKER llvm-link PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) -find_program(CMAKE_NM llvm-nm PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) -find_program(CMAKE_OBJDUMP llvm-objdump PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) -find_program(CMAKE_RANLIB llvm-ranlib PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) -find_program(CMAKE_OBJCOPY objcopy PATH ${TOOLCHAIN_HOME}) -find_program(CMAKE_READELF readelf PATH ${TOOLCHAIN_HOME}) - -foreach(file_name include include-fixed) +if(DEFINED TOOLCHAIN_HOME) + set(find_program_clang_args PATH ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) + set(find_program_binutils_args PATH ${TOOLCHAIN_HOME}) +endif() + + +find_program(CMAKE_C_COMPILER clang ${find_program_clang_args}) +find_program(CMAKE_CXX_COMPILER clang++ ${find_program_clang_args}) +find_program(CMAKE_AR llvm-ar ${find_program_clang_args}) +find_program(CMAKE_LINKER llvm-link ${find_program_clang_args}) +find_program(CMAKE_NM llvm-nm ${find_program_clang_args}) +find_program(CMAKE_OBJDUMP llvm-objdump ${find_program_clang_args}) +find_program(CMAKE_RANLIB llvm-ranlib ${find_program_clang_args}) + +find_program(CMAKE_OBJCOPY objcopy ${find_program_binutils_args}) +find_program(CMAKE_READELF readelf ${find_program_binutils_args}) + +if(NOT "${ARCH}" STREQUAL "posix") + + foreach(file_name include include-fixed) + execute_process( + COMMAND ${CMAKE_C_COMPILER} --print-file-name=${file_name} + OUTPUT_VARIABLE _OUTPUT + ) + string(REGEX REPLACE "\n" "" _OUTPUT ${_OUTPUT}) + + list(APPEND NOSTDINC ${_OUTPUT}) + endforeach() + + foreach(isystem_include_dir ${NOSTDINC}) + list(APPEND isystem_include_flags -isystem ${isystem_include_dir}) + endforeach() + + # This libgcc code is partially duplicated in compiler/*/target.cmake execute_process( - COMMAND ${CMAKE_C_COMPILER} --print-file-name=${file_name} - OUTPUT_VARIABLE _OUTPUT + COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} --print-libgcc-file-name + OUTPUT_VARIABLE LIBGCC_FILE_NAME + OUTPUT_STRIP_TRAILING_WHITESPACE ) - string(REGEX REPLACE "\n" "" _OUTPUT ${_OUTPUT}) - list(APPEND NOSTDINC ${_OUTPUT}) -endforeach() + assert_exists(LIBGCC_FILE_NAME) -foreach(isystem_include_dir ${NOSTDINC}) - list(APPEND isystem_include_flags -isystem ${isystem_include_dir}) -endforeach() + get_filename_component(LIBGCC_DIR ${LIBGCC_FILE_NAME} DIRECTORY) -# This libgcc code is partially duplicated in compiler/*/target.cmake -execute_process( - COMMAND ${CMAKE_C_COMPILER} ${TOOLCHAIN_C_FLAGS} --print-libgcc-file-name - OUTPUT_VARIABLE LIBGCC_FILE_NAME - OUTPUT_STRIP_TRAILING_WHITESPACE - ) + assert_exists(LIBGCC_DIR) -assert_exists(LIBGCC_FILE_NAME) + list(APPEND LIB_INCLUDE_DIR "-L\"${LIBGCC_DIR}\"") + list(APPEND TOOLCHAIN_LIBS gcc) -get_filename_component(LIBGCC_DIR ${LIBGCC_FILE_NAME} DIRECTORY) + set(CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags} -Wl,--unresolved-symbols=ignore-in-object-files) + string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") -assert_exists(LIBGCC_DIR) +endif() -list(APPEND LIB_INCLUDE_DIR "-L\"${LIBGCC_DIR}\"") -list(APPEND TOOLCHAIN_LIBS gcc) +# Load toolchain_cc-family macros -set(CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags} -Wl,--unresolved-symbols=ignore-in-object-files) -string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") +macro(toolchain_cc_nostdinc) + if(NOT "${ARCH}" STREQUAL "posix") + zephyr_compile_options( -nostdinc) + endif() +endmacro() -# Load toolchain_cc-family macros # Clang and GCC are almost feature+flag compatible, so reuse freestanding gcc -include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_fortify.cmake) include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_canaries.cmake) include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_optimizations.cmake) include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_cpp.cmake) include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_asm.cmake) include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_baremetal.cmake) + +macro(toolchain_cc_security_fortify) + # No op, clang doesn't understand fortify at all +endmacro() + +macro(toolchain_cc_no_freestanding_options) + # No op, this is used by the native_posix, clang has problems + # compiling the native_posix with -fno-freestanding. +endmacro() diff --git a/cmake/compiler/gcc/target.cmake b/cmake/compiler/gcc/target.cmake index a4030c08ef704..3451b67fe4cd2 100644 --- a/cmake/compiler/gcc/target.cmake +++ b/cmake/compiler/gcc/target.cmake @@ -132,6 +132,7 @@ list(APPEND CMAKE_REQUIRED_FLAGS -nostartfiles -nostdlib ${isystem_include_flags string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") # Load toolchain_cc-family macros +include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_freestanding.cmake) include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_security_fortify.cmake) include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_security_canaries.cmake) include(${ZEPHYR_BASE}/cmake/compiler/${COMPILER}/target_optimizations.cmake) diff --git a/cmake/compiler/gcc/target_freestanding.cmake b/cmake/compiler/gcc/target_freestanding.cmake new file mode 100644 index 0000000000000..3648ecf8f4566 --- /dev/null +++ b/cmake/compiler/gcc/target_freestanding.cmake @@ -0,0 +1,8 @@ +# Copyright (c) 2019 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +macro(toolchain_cc_no_freestanding_options) + + zephyr_cc_option(-fno-freestanding) + +endmacro() diff --git a/cmake/compiler/host-gcc/target.cmake b/cmake/compiler/host-gcc/target.cmake index 8dc58dd3a63f9..8eaf816e62ad0 100644 --- a/cmake/compiler/host-gcc/target.cmake +++ b/cmake/compiler/host-gcc/target.cmake @@ -81,6 +81,7 @@ endforeach() # Load toolchain_cc-family macros # Significant overlap with freestanding gcc compiler so reuse it +include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_freestanding.cmake) include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_fortify.cmake) include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_security_canaries.cmake) include(${ZEPHYR_BASE}/cmake/compiler/gcc/target_optimizations.cmake) diff --git a/cmake/generic_toolchain.cmake b/cmake/generic_toolchain.cmake index 83843a1300e2d..8cb0947e78f2d 100644 --- a/cmake/generic_toolchain.cmake +++ b/cmake/generic_toolchain.cmake @@ -41,6 +41,11 @@ if("${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "gccarmemb") set(ZEPHYR_TOOLCHAIN_VARIANT "gnuarmemb") endif() +# Host-tools don't unconditionally set TOOLCHAIN_HOME anymore, +# but in case Zephyr's SDK toolchain is used, set TOOLCHAIN_HOME +if("${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "zephyr") + set(TOOLCHAIN_HOME ${HOST_TOOLS_HOME}) +endif() set(TOOLCHAIN_ROOT ${TOOLCHAIN_ROOT} CACHE STRING "Zephyr toolchain root") assert(TOOLCHAIN_ROOT "Zephyr toolchain root path invalid: please set the TOOLCHAIN_ROOT-variable") @@ -50,7 +55,9 @@ assert(ZEPHYR_TOOLCHAIN_VARIANT "Zephyr toolchain variant invalid: please set th # Pick host system's toolchain if we are targeting posix if((${ARCH} STREQUAL "posix") OR (${ARCH} STREQUAL "x86_64")) - set(ZEPHYR_TOOLCHAIN_VARIANT "host") + if(NOT "${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "llvm") + set(ZEPHYR_TOOLCHAIN_VARIANT "host") + endif() endif() # Configure the toolchain based on what SDK/toolchain is in use. diff --git a/cmake/toolchain/llvm/generic.cmake b/cmake/toolchain/llvm/generic.cmake index 88356a52cdbbf..5925e00f9215c 100644 --- a/cmake/toolchain/llvm/generic.cmake +++ b/cmake/toolchain/llvm/generic.cmake @@ -1,9 +1,16 @@ # SPDX-License-Identifier: Apache-2.0 -set(CLANG_ROOT $ENV{CLANG_ROOT_DIR}) -set_ifndef(CLANG_ROOT /usr) +find_appropriate_cache_directory(USER_CACHE_DIR) -set(TOOLCHAIN_HOME ${CLANG_ROOT}/bin/) +if((NOT "${USER_CACHE_DIR}" STREQUAL "") AND (EXISTS "${USER_CACHE_DIR}")) + message(STATUS "Invalidating toolchain capability cache in ${USER_CACHE_DIR}") + execute_process(COMMAND + ${CMAKE_COMMAND} -E remove_directory "${USER_CACHE_DIR}") +endif() + +if(DEFINED $ENV{CLANG_ROOT_DIR}) + set(TOOLCHAIN_HOME ${CLANG_ROOT}/bin/) +endif() set(COMPILER clang) @@ -17,3 +24,7 @@ endif() set(CMAKE_C_COMPILER_TARGET ${triple}) set(CMAKE_ASM_COMPILER_TARGET ${triple}) set(CMAKE_CXX_COMPILER_TARGET ${triple}) + +if("${ARCH}" STREQUAL "posix") + set(TOOLCHAIN_HAS_NEWLIB OFF CACHE BOOL "True if toolchain supports newlib") +endif() diff --git a/cmake/toolchain/zephyr/0.9.5/host-tools.cmake b/cmake/toolchain/zephyr/0.9.5/host-tools.cmake index 68f0761f3c766..47e5304b9a5a9 100644 --- a/cmake/toolchain/zephyr/0.9.5/host-tools.cmake +++ b/cmake/toolchain/zephyr/0.9.5/host-tools.cmake @@ -1,16 +1,16 @@ # SPDX-License-Identifier: Apache-2.0 if(MINGW) - set(TOOLCHAIN_HOME ${ZEPHYR_SDK_INSTALL_DIR}/sysroots/i686-pokysdk-mingw32) + set(HOST_TOOLS_HOME ${ZEPHYR_SDK_INSTALL_DIR}/sysroots/i686-pokysdk-mingw32) else() - set(TOOLCHAIN_HOME ${ZEPHYR_SDK_INSTALL_DIR}/sysroots/${TOOLCHAIN_ARCH}-pokysdk-linux) + set(HOST_TOOLS_HOME ${ZEPHYR_SDK_INSTALL_DIR}/sysroots/${TOOLCHAIN_ARCH}-pokysdk-linux) endif() # Path used for searching by the find_*() functions, with appropriate # suffixes added. Ensures that the SDK's host tools will be found when # we call, e.g. find_program(QEMU qemu-system-x86) -list(APPEND CMAKE_PREFIX_PATH ${TOOLCHAIN_HOME}/usr) +list(APPEND CMAKE_PREFIX_PATH ${HOST_TOOLS_HOME}/usr) # TODO: Use find_* somehow for these as well? -set_ifndef(QEMU_BIOS ${TOOLCHAIN_HOME}/usr/share/qemu) -set_ifndef(OPENOCD_DEFAULT_PATH ${TOOLCHAIN_HOME}/usr/share/openocd/scripts) +set_ifndef(QEMU_BIOS ${HOST_TOOLS_HOME}/usr/share/qemu) +set_ifndef(OPENOCD_DEFAULT_PATH ${HOST_TOOLS_HOME}/usr/share/openocd/scripts) diff --git a/doc/getting_started/index.rst b/doc/getting_started/index.rst index e31adcd41a458..1ce54db8b971b 100644 --- a/doc/getting_started/index.rst +++ b/doc/getting_started/index.rst @@ -156,7 +156,8 @@ Set Up a Toolchain In some specific configurations like non-MCU x86 targets on Linux, you may be able to re-use the native development tools provided by your operating system instead of an SDK by setting - ``ZEPHYR_TOOLCHAIN_VARIANT=host``. + ``ZEPHYR_TOOLCHAIN_VARIANT=host`` for gcc or + ``ZEPHYR_TOOLCHAIN_VARIANT=llvm`` for clang. If you want, you can use the SDK host tools (such as OpenOCD) with a different toolchain by keeping the :envvar:`ZEPHYR_SDK_INSTALL_DIR`