1# SPDX-License-Identifier: Apache-2.0
2
3if (NOT CMAKE_HOST_UNIX OR CMAKE_HOST_APPLE)
4  message(FATAL_ERROR "The POSIX architecture only works on Linux. If on Windows or macOS "
5          "consider using a virtual machine to run a Linux guest.")
6endif()
7
8# This native_simulator library is used to pass options to the
9# native_simulator runner build. Currently the following are used:
10#  INTERFACE_COMPILE_OPTIONS:
11#      Extra compile options to be used during the build of the runner files
12#      For ex. target_compile_options(native_simulator INTERFACE "-m64")
13#  INTERFACE_LINK_OPTIONS:
14#      Extra link options to be passed during the *final* link of the runner
15#      with the embedded SW.
16#      For ex. target_link_options(native_simulator INTERFACE "-lstdc++")
17#  INTERFACE_SOURCES:
18#      Extra sources to be built in the native simulator runner context
19#      For ex. target_sources(native_simulator INTERFACE silly.c)
20#      Note that these are built with the host libC and the include directories
21#      the runner is built with.
22#  RUNNER_LINK_LIBRARIES:
23#      Extra libraries to link with the runner
24#      For ex. set_property(TARGET native_simulator APPEND PROPERTY RUNNER_LINK_LIBRARIES "mylib.a")
25#  LOCALIZE_EXTRA_OPTIONS:
26#      Extra options to be passed to objcopy when localizing each Zephyr MCU image symbols
27#      This can be used to hide symbols a library may have set as visible outside of
28#      itself once the MCU image has been assembled.
29#      For ex. set_property(TARGET native_simulator APPEND PROPERTY LOCALIZE_EXTRA_OPTIONS "--localize-symbol=spinel*")
30#  Note: target_link_libraries() cannot be used on this library at this point.
31#        target_link_libraries() updates INTERFACE_LINK_LIBRARIES but wrapping it with extra
32#        information. This means we cannot directly pass it to the native_simulator runner build.
33#        Check https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_LINK_LIBRARIES.html for more
34#        info.
35#        We use target_link_options() instead
36add_library(native_simulator INTERFACE)
37set_property(TARGET native_simulator PROPERTY RUNNER_LINK_LIBRARIES "")
38set_property(TARGET native_simulator PROPERTY LOCALIZE_EXTRA_OPTIONS "")
39
40set(NSI_DIR ${ZEPHYR_BASE}/scripts/native_simulator CACHE PATH "Path to the native simulator")
41
42if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/${CMAKE_HOST_SYSTEM_NAME}.${CMAKE_HOST_SYSTEM_PROCESSOR}.cmake)
43  # @Intent: Set necessary compiler & linker options for this specific host architecture & OS
44  include(${CMAKE_HOST_SYSTEM_NAME}.${CMAKE_HOST_SYSTEM_PROCESSOR}.cmake)
45else() # Linux.x86_64
46  if (CONFIG_64BIT)
47    # some gcc versions fail to build without -fPIC
48    zephyr_compile_options(-m64 -fPIC)
49    zephyr_link_libraries(-m64)
50
51    target_link_options(native_simulator INTERFACE "-m64")
52    target_compile_options(native_simulator INTERFACE "-m64")
53  else ()
54    zephyr_compile_options(-m32)
55    zephyr_link_libraries(-m32)
56
57    target_link_options(native_simulator INTERFACE "-m32")
58    target_compile_options(native_simulator INTERFACE "-m32")
59
60    # When building for 32bits x86, gcc defaults to using the old 8087 float arithmetic
61    # which causes some issues with literal float comparisons. So we set it
62    # to use the SSE2 float path instead
63    # (clang defaults to use SSE, but, setting this option for it is safe)
64    check_set_compiler_property(APPEND PROPERTY fpsse2 "SHELL:-msse2 -mfpmath=sse")
65    zephyr_compile_options($<TARGET_PROPERTY:compiler,fpsse2>)
66    target_compile_options(native_simulator INTERFACE "$<TARGET_PROPERTY:compiler,fpsse2>")
67  endif ()
68endif()
69
70zephyr_compile_options(
71  ${ARCH_FLAG}
72  )
73
74if (CONFIG_NATIVE_APPLICATION)
75  zephyr_compile_options(
76    -include ${ZEPHYR_BASE}/arch/posix/include/posix_cheats.h
77  )
78elseif (CONFIG_NATIVE_LIBRARY)
79  zephyr_compile_options(
80    -fvisibility=hidden
81  )
82
83  # While doing the partial linking of the native library, some symbols will be missing
84  # which are provided by the native simulator runner
85  zephyr_ld_options(
86    -Wl,--unresolved-symbols=ignore-all
87  )
88
89  if (NOT CONFIG_EXTERNAL_LIBC)
90    # Get the *compiler* include path, that is where the *compiler* provided headers are (not the
91    # default libC ones). This includes basic headers like stdint.h, stddef.h or float.h
92    # We expect something like
93    #  /usr/lib/gcc/x86_64-linux-gnu/12/include or /usr/lib/llvm-14/lib/clang/14.0.0/include
94    execute_process(
95      COMMAND ${CMAKE_C_COMPILER} --print-file-name=include/stddef.h
96      OUTPUT_VARIABLE _OUTPUT
97      COMMAND_ERROR_IS_FATAL ANY
98    )
99    get_filename_component(COMPILER_OWN_INCLUDE_PATH "${_OUTPUT}" DIRECTORY)
100
101    # Do not use the C library from this compiler/host,
102    # but still use the basic compiler headers
103    # no_builtin to avoid the compiler using builtin replacements for std library functions
104    zephyr_compile_options(
105      -nostdinc
106      -isystem ${COMPILER_OWN_INCLUDE_PATH}
107      $<TARGET_PROPERTY:compiler,freestanding>
108      $<TARGET_PROPERTY:compiler,no_builtin>
109    )
110  endif()
111
112  if (CONFIG_COMPILER_WARNINGS_AS_ERRORS)
113    target_compile_options(native_simulator INTERFACE $<TARGET_PROPERTY:compiler,warnings_as_errors>)
114  endif()
115endif()
116
117if(CONFIG_EXTERNAL_LIBC)
118  # @Intent: Obtain compiler specific flags for no freestanding compilation
119  zephyr_compile_options($<TARGET_PROPERTY:compiler,hosted>)
120endif()
121
122if(CONFIG_EXTERNAL_LIBCPP)
123  target_link_options(native_simulator INTERFACE "-lstdc++")
124endif()
125
126zephyr_include_directories(${BOARD_DIR})
127
128if(CONFIG_COVERAGE)
129  target_compile_options(native_simulator INTERFACE $<TARGET_PROPERTY:compiler,coverage>)
130  target_link_options(native_simulator INTERFACE $<TARGET_PROPERTY:linker,coverage>)
131endif()
132
133if (CONFIG_GPROF)
134  zephyr_compile_options($<TARGET_PROPERTY:compiler,gprof>)
135  zephyr_link_libraries($<TARGET_PROPERTY:linker,gprof>)
136
137  target_link_options(native_simulator INTERFACE "-pg")
138endif()
139
140if (CONFIG_NATIVE_APPLICATION)
141  zephyr_ld_options(
142    -ldl
143    -pthread
144  )
145endif()
146
147# About the -include directive: The reason to do it this way, is because in this
148# manner it is transparent to the application. Otherwise posix_cheats.h needs to
149# be included in all the applications' files which define main( ), and in any
150# app file which uses the pthreads like API provided by Zephyr
151# ( include/posix/pthread.h / kernel/pthread.c ) [And any future API added to
152# Zephyr which will clash with the native POSIX API] . It would also need to
153# be included in a few zephyr kernel files.
154
155#
156# Support for the LLVM Sanitizer toolchain instrumentation frameworks
157# (supported by current gcc's as well)
158#
159
160if(CONFIG_ASAN)
161  list(APPEND LLVM_SANITIZERS "address")
162endif()
163
164if(CONFIG_MSAN)
165  list(APPEND LLVM_SANITIZERS "memory")
166endif()
167
168if(CONFIG_UBSAN)
169  list(APPEND LLVM_SANITIZERS "undefined")
170endif()
171
172if(CONFIG_ASAN_RECOVER)
173  zephyr_compile_options(-fsanitize-recover=all)
174endif()
175
176if(CONFIG_ARCH_POSIX_LIBFUZZER)
177  list(APPEND LLVM_SANITIZERS "fuzzer")
178  if(NOT CONFIG_64BIT)
179    # On i386, libfuzzer seems to dynamically relocate the binary, so
180    # we need to emit PIC code.  This limitation is undocumented and
181    # poorly understood...
182    zephyr_compile_options(-fPIC)
183  endif()
184endif()
185
186list(JOIN LLVM_SANITIZERS "," LLVM_SANITIZERS_ARG)
187if(NOT ${LLVM_SANITIZERS_ARG} STREQUAL "")
188  set(LLVM_SANITIZERS_ARG "-fsanitize=${LLVM_SANITIZERS_ARG}")
189  zephyr_compile_options("${LLVM_SANITIZERS_ARG}")
190  zephyr_link_libraries("${LLVM_SANITIZERS_ARG}")
191
192  target_link_options(native_simulator INTERFACE ${LLVM_SANITIZERS_ARG})
193  target_compile_options(native_simulator INTERFACE ${LLVM_SANITIZERS_ARG})
194endif()
195
196# Override the C standard used for compilation to C 2011
197# This is due to some tests using _Static_assert which is a 2011 feature, but
198# otherwise relying on compilers supporting it also when set to C99.
199# This was in general ok, but with some host compilers and C library versions
200# it led to problems. So we override it to 2011 for native_posix.
201set_property(GLOBAL PROPERTY CSTD c11)
202
203add_subdirectory(core)
204