zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.89k stars 6.63k forks source link

host toolchain for x86 fails on empty CMAKE_C_FLAGS #21614

Closed b0661 closed 4 years ago

b0661 commented 4 years ago

Describe the bug

Selecting ZEPHYR_TOOLCHAIN_VARIANT=host on Ubuntu x86_64 causes CMake to bail out with:

CMake Error at /home/bobby/projects/zephyr/cmake/compiler/host-gcc/target.cmake:26 (STRING):
  STRING sub-command REGEX, mode REPLACE needs at least 6 arguments total to
  command.
Call Stack (most recent call first):
  /home/bobby/projects/zephyr/cmake/target_toolchain.cmake:49 (include)
  /home/bobby/projects/zephyr/cmake/app/boilerplate.cmake:473 (include)
  CMakeLists.txt:7 (include)

To Reproduce

Bug showed up in internal test environment. Don't know whether this hits Zephyr's "normal" usage of the host toolchain.

The problem seems to be that all compiler flags are already compiled in the host compiler and there is no need for CMAKE_C_FLAGS. The code at cmake/compiler/host-gcc/target.cmake is not prepared for an empty CMAKE_C_FLAGS variable.

The following code helped to avoid the bug:

diff --git a/cmake/compiler/host-gcc/target.cmake b/cmake/compiler/host-gcc/target.cmake
index 35626aecac..0ee5a6544c 100644
--- a/cmake/compiler/host-gcc/target.cmake
+++ b/cmake/compiler/host-gcc/target.cmake
@@ -22,6 +22,11 @@ find_program(CMAKE_CXX_COMPILER ${cplusplus_compiler}     CACHE INTERNAL " " FOR
 # -mx32 --print-libgcc-file-name) so don't fail to build for something
 # that is currently not needed. See comments in compiler/gcc/target.cmake
 if (CONFIG_X86)
+  # Note that CMAKE_C_FLAGS may be an empty string, and
+  # STRING(REGEX REPLACE ... does not work with an empty string.
+  if(NOT CMAKE_C_FLAGS)
+    set(CMAKE_C_FLAGS -v)
+  endif()
   # Convert to list as cmake Modules/*.cmake do it
   STRING(REGEX REPLACE " +" ";" PRINT_LIBGCC_ARGS ${CMAKE_C_FLAGS})
   # This libgcc code is partially duplicated in compiler/*/target.cmake

Expected behavior Host toolchain to work even if CMAKE_C_FLAGS is empty.

Impact annoyance

Screenshots or console output N/A

Environment (please complete the following information):

Additional context N/A

SebastianBoe commented 4 years ago

Hi, I would prefer this patch:

diff --git a/cmake/compiler/host-gcc/target.cmake b/cmake/compiler/host-gcc/target.cmake
index 35626aecac..11c817314b 100644
--- a/cmake/compiler/host-gcc/target.cmake
+++ b/cmake/compiler/host-gcc/target.cmake
@@ -23,10 +23,10 @@ find_program(CMAKE_CXX_COMPILER ${cplusplus_compiler}     CACHE INTERNAL " " FOR
 # that is currently not needed. See comments in compiler/gcc/target.cmake
 if (CONFIG_X86)
   # Convert to list as cmake Modules/*.cmake do it
-  STRING(REGEX REPLACE " +" ";" PRINT_LIBGCC_ARGS ${CMAKE_C_FLAGS})
+  STRING(REGEX REPLACE " +" ";" PRINT_LIBGCC_ARGS "${CMAKE_C_FLAGS}")
   # This libgcc code is partially duplicated in compiler/*/target.cmake
   execute_process(
-    COMMAND ${CMAKE_C_COMPILER} ${PRINT_LIBGCC_ARGS} --print-libgcc-file-name
+    COMMAND ${CMAKE_C_COMPILER} "${PRINT_LIBGCC_ARGS}" --print-libgcc-file-name
     OUTPUT_VARIABLE LIBGCC_FILE_NAME
     OUTPUT_STRIP_TRAILING_WHITESPACE
     )

But I get another, presumably unrelated, error later in the build:

[33/108] Building C object zephyr/CMakeFiles/zephyr.dir/drivers/timer/hpet.c.obj
FAILED: zephyr/CMakeFiles/zephyr.dir/drivers/timer/hpet.c.obj 
ccache /usr/bin/gcc -DBUILD_VERSION=zephyr-v2.1.0-581-g4e135d76a3c2 -DKERNEL -D_FORTIFY_SOURCE=2 -D__ZEPHYR__=1 -I../../../include -I../../../include/drivers -Izephyr/include/generated -I../../../soc/x86/ia32 -isystem ../../../lib/libc/minimal/include -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include -Os -imacros/home/sebo/ncs/zephyr/samples/hello_world/outdir/zephyr/include/generated/autoconf.h -ffreestanding -fno-common -g -imacros/home/sebo/ncs/zephyr/include/toolchain/zephyr_stdint.h -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wno-main -Wno-pointer-sign -Wpointer-arith -Wno-unused-but-set-variable -Werror=implicit-int -fno-asynchronous-unwind-tables -fno-pie -fno-pic -fno-strict-overflow -fno-reorder-functions -fno-defer-pop -ffunction-sections -fdata-sections -mno-sse -std=c99 -nostdinc -MD -MT zephyr/CMakeFiles/zephyr.dir/drivers/timer/hpet.c.obj -MF zephyr/CMakeFiles/zephyr.dir/drivers/timer/hpet.c.obj.d -o zephyr/CMakeFiles/zephyr.dir/drivers/timer/hpet.c.obj   -c /home/sebo/ncs/zephyr/drivers/timer/hpet.c
../../../include/arch/x86/ia32/arch.h: Assembler messages:
../../../include/arch/x86/ia32/arch.h:353: Error: invalid instruction suffix for `pushf'
../../../include/arch/x86/ia32/arch.h:353: Error: invalid instruction suffix for `pop'
/home/sebo/ncs/zephyr/drivers/timer/hpet.c:98: Error: invalid instruction suffix for `push'
/home/sebo/ncs/zephyr/drivers/timer/hpet.c:99: Error: invalid instruction suffix for `push'
../../../include/arch/x86/ia32/arch.h:353: Error: invalid instruction suffix for `pushf'
../../../include/arch/x86/ia32/arch.h:353: Error: invalid instruction suffix for `pop'
../../../include/arch/x86/ia32/arch.h:353: Error: invalid instruction suffix for `pushf'
../../../include/arch/x86/ia32/arch.h:353: Error: invalid instruction suffix for `pop'
[34/108] Building C object zephyr/arch/arch/x86/core/CMakeFiles/arch__x86__core.dir/prep_c.c.obj

so before applying it I would appreciate it if you could confirm this patch works on your system.

b0661 commented 4 years ago

@SebastianBoe, the patch works for me. Thanks.