blob: 78a7c47bede2b389f67360ef5e0ced0a54a6cc7e [file] [log] [blame]
Imre Kisdd154112021-10-08 11:21:14 +02001#-------------------------------------------------------------------------------
Gyorgy Szing51f45d22021-12-08 00:44:18 +00002# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
Imre Kisdd154112021-10-08 11:21:14 +02003#
4# SPDX-License-Identifier: BSD-3-Clause
5#
6#-------------------------------------------------------------------------------
7
Gyorgy Szing51f45d22021-12-08 00:44:18 +00008# Add newlib specific porting files to the project.
Gyorgy Szing693877e2021-12-12 02:51:10 +01009if (NOT DEFINED TGT)
10 message(FATAL_ERROR "mandatory parameter TGT is not defined.")
11endif()
12
Imre Kis217192d2021-12-17 14:04:43 +010013# Adding libc interface
14add_components(TARGET ${TGT}
15 BASE_DIR ${TS_ROOT}
16 COMPONENTS
17 components/common/libc
18)
19
Gyorgy Szing693877e2021-12-12 02:51:10 +010020# Compile TS specific newlib porting files.
21target_sources(${TGT} PRIVATE
22 "${CMAKE_CURRENT_LIST_DIR}/newlib_init.c"
23 "${CMAKE_CURRENT_LIST_DIR}/newlib_sp_assert.c"
24 "${CMAKE_CURRENT_LIST_DIR}/newlib_sp_heap.c"
25)
26
Gyorgy Szing51f45d22021-12-08 00:44:18 +000027# Fetch newlib from external repository
28set(NEWLIB_URL "https://sourceware.org/git/newlib-cygwin.git"
29 CACHE STRING "newlib repository URL")
30set(NEWLIB_REFSPEC "newlib-4.1.0"
31 CACHE STRING "newlib git refspec")
32set(NEWLIB_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/newlib-src"
33 CACHE PATH "newlib source-code location")
34set(NEWLIB_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/newlib_install"
35 CACHE PATH "newlib installation directory")
Imre Kisdd154112021-10-08 11:21:14 +020036
Gyorgy Szing693877e2021-12-12 02:51:10 +010037# Extracting compiler prefix without the trailing hyphen from the C compiler name
Imre Kisdd154112021-10-08 11:21:14 +020038get_filename_component(COMPILER_PATH ${CMAKE_C_COMPILER} DIRECTORY)
39get_filename_component(COMPILER_NAME ${CMAKE_C_COMPILER} NAME)
Imre Kis2b7ef372022-01-04 12:36:12 +010040string(REGEX REPLACE "(.*)-[^-]+$" "\\1" COMPILER_PREFIX ${COMPILER_NAME})
Imre Kisdd154112021-10-08 11:21:14 +020041
Gyorgy Szing51f45d22021-12-08 00:44:18 +000042find_library(NEWLIB_LIBC_PATH
43 NAMES libc.a c.a libc.lib c.lib
44 PATHS ${NEWLIB_INSTALL_DIR}
45 PATH_SUFFIXES "${COMPILER_PREFIX}/lib"
46 DOC "Location of newlib::libc library."
47 NO_DEFAULT_PATH
Imre Kisdd154112021-10-08 11:21:14 +020048)
Gyorgy Szing51f45d22021-12-08 00:44:18 +000049set(NEWLIB_LIBC_PATH ${NEWLIB_LIBC_PATH})
50unset(NEWLIB_LIBC_PATH CACHE)
Imre Kisdd154112021-10-08 11:21:14 +020051
Gyorgy Szing51f45d22021-12-08 00:44:18 +000052find_library(NEWLIB_LIBNOSYS_PATH
53 NAMES libnosys.a nosys.a nosys.lib nosys.lib
54 PATHS ${NEWLIB_INSTALL_DIR}
55 PATH_SUFFIXES "${COMPILER_PREFIX}/lib"
56 DOC "Location of newlib::libnosys library."
57 NO_DEFAULT_PATH
58)
Gyorgy Szingf7a91e72022-02-09 11:59:07 +010059set(NEWLIB_LIBNOSYS_PATH ${NEWLIB_LIBNOSYS_PATH})
Gyorgy Szing51f45d22021-12-08 00:44:18 +000060unset(NEWLIB_LIBNOSYS_PATH CACHE)
61
62if (NOT NEWLIB_LIBC_PATH)
63 # Determine the number of processes to run while running parallel builds.
64 # Pass -DPROCESSOR_COUNT=<n> to cmake to override.
65 if(NOT DEFINED PROCESSOR_COUNT)
66 include(ProcessorCount)
67 ProcessorCount(PROCESSOR_COUNT)
68 set(PROCESSOR_COUNT ${PROCESSOR_COUNT}
69 CACHE STRING "Number of cores to use for parallel builds.")
70 endif()
71
72 # See if the source is available locally
73 find_file(NEWLIB_HEADER_FILE
74 NAMES newlib.h
75 PATHS ${NEWLIB_SOURCE_DIR}
76 PATH_SUFFIXES "newlib/libc/include"
77 NO_DEFAULT_PATH
78 )
79 set(NEWLIB_HEADER_FILE ${NEWLIB_HEADER_FILE})
80 unset(NEWLIB_HEADER_FILE CACHE)
81
82 # Source not found, fetch it.
83 if (NOT NEWLIB_HEADER_FILE)
84 include(FetchContent)
85
86 # Checking git
87 find_program(GIT_COMMAND "git")
88 if (NOT GIT_COMMAND)
89 message(FATAL_ERROR "Please install git")
90 endif()
91
Gyorgy Szingb202de32022-09-15 21:37:17 +020092 # List patch files.
93 file(GLOB _patch_files LIST_DIRECTORIES false "${CMAKE_CURRENT_LIST_DIR}/[0-9]*-[!0-9]*.patch")
94 # Sort items in natural order to ensure patches are amended in the right order.
95 list(SORT _patch_files COMPARE NATURAL)
96 # Convert the list to a string of concatenated quoted list items.
97 string(REPLACE ";" "\" \"" _patch_files "${_patch_files}")
98 set(_patch_files "\"${_patch_files}\"")
99 # Create a shell script pathching newlib witht the files listed above
100 string(APPEND _patch_script "#!/bin/sh\n"
101 " ${GIT_COMMAND} stash\n"
102 " ${GIT_COMMAND} branch ts-bf-am\n"
103 " ${GIT_COMMAND} am ${_patch_files}\n"
104 " ${GIT_COMMAND} reset ts-bf-am\n"
105 " ${GIT_COMMAND} branch -D ts-bf-am\n"
106 )
107 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/patch-newlib "${_patch_script}")
108
Gyorgy Szing51f45d22021-12-08 00:44:18 +0000109 # Fetching newlib
110 FetchContent_Declare(
111 newlib
112 SOURCE_DIR ${NEWLIB_SOURCE_DIR}
113 GIT_REPOSITORY ${NEWLIB_URL}
114 GIT_TAG ${NEWLIB_REFSPEC}
Julian Halla628af32022-04-01 10:08:18 +0100115 GIT_SHALLOW FALSE
Gyorgy Szingb202de32022-09-15 21:37:17 +0200116 PATCH_COMMAND sh ${CMAKE_CURRENT_BINARY_DIR}/patch-newlib
Gyorgy Szing51f45d22021-12-08 00:44:18 +0000117 )
118
119 # FetchContent_GetProperties exports newlib_SOURCE_DIR and newlib_BINARY_DIR variables
120 FetchContent_GetProperties(newlib)
121 # FetchContent_Populate will fail if the source directory is removed since it will try to
122 # do an "update" and not a "populate" action. As a workaround, remove the subbuild directory.
123 # Note: this fix assumes, the default subbuild location is used.
124 file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/_deps/newlib-subbuild")
125
126 if(NOT newlib_POPULATED)
127 message(STATUS "Fetching newlib")
128 FetchContent_Populate(newlib)
129 endif()
130 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${NEWLIB_SOURCE_DIR})
131 endif()
132
Gyorgy Szingb202de32022-09-15 21:37:17 +0200133 # Split a newlib extra build parameter into a list of parameters
134 set(NEWLIB_EXTRAS ${NEWLIB_EXTRA})
135 separate_arguments(NEWLIB_EXTRAS)
136
Gyorgy Szing51f45d22021-12-08 00:44:18 +0000137 # Newlib configure step
138 # CC env var must be unset otherwise configure will assume the cross compiler is the host
139 # compiler.
140 # The configure options are set to minimize code size and memory usage.
141 execute_process(COMMAND
142 ${CMAKE_COMMAND} -E env --unset=CC PATH=${COMPILER_PATH}:$ENV{PATH} ./configure
143 --target=${COMPILER_PREFIX}
Gyorgy Szingb202de32022-09-15 21:37:17 +0200144 --host=${COMPILER_PREFIX}
Gyorgy Szing51f45d22021-12-08 00:44:18 +0000145 --prefix=${NEWLIB_INSTALL_DIR}
146 --enable-newlib-nano-formatted-io
147 --enable-newlib-nano-malloc
148 --enable-lite-exit
149 --enable-newlib-reent-small
150 --enable-newlib-global-atexit
151 --disable-multilib
Gyorgy Szingb202de32022-09-15 21:37:17 +0200152 ${NEWLIB_EXTRAS}
Mark Dykese9db8172022-07-21 14:10:00 -0500153 CFLAGS_FOR_TARGET=-fpic
Gyorgy Szing51f45d22021-12-08 00:44:18 +0000154 LDFLAGS_FOR_TARGET=-fpie
155 WORKING_DIRECTORY
156 ${NEWLIB_SOURCE_DIR}
157 RESULT_VARIABLE _newlib_error
158 )
159
160 if (_newlib_error)
161 message(FATAL_ERROR "Configuration step of newlib failed with ${_newlib_error}.")
162 endif()
163
164 # Newlib build step
165 execute_process(COMMAND
166 ${CMAKE_COMMAND} -E env --unset=CC PATH=${COMPILER_PATH}:$ENV{PATH}
167 make -j${PROCESSOR_COUNT}
168 WORKING_DIRECTORY
169 ${NEWLIB_SOURCE_DIR}
170 RESULT_VARIABLE _newlib_error
171 )
172
173 if (_newlib_error)
174 message(FATAL_ERROR "Build step of newlib failed with ${_newlib_error}.")
175 endif()
176
177 # Newlib install step
178 execute_process(COMMAND
179 ${CMAKE_COMMAND} -E env --unset=CC PATH=${COMPILER_PATH}:$ENV{PATH} make install
180 WORKING_DIRECTORY
181 ${NEWLIB_SOURCE_DIR}
182 RESULT_VARIABLE _newlib_error
183 )
184
185 if (_newlib_error)
186 message(FATAL_ERROR "Install step of newlib failed with ${_newlib_error}.")
187 endif()
188
189 set(NEWLIB_LIBC_PATH "${NEWLIB_INSTALL_DIR}/${COMPILER_PREFIX}/lib/libc.a")
190 set(NEWLIB_LIBNOSYS_PATH "${NEWLIB_INSTALL_DIR}/${COMPILER_PREFIX}/lib/libnosys.a")
Imre Kisdd154112021-10-08 11:21:14 +0200191endif()
192
Gyorgy Szing51f45d22021-12-08 00:44:18 +0000193set_property(DIRECTORY ${CMAKE_SOURCE_DIR}
194 APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${NEWLIB_LIBC_PATH})
Imre Kisdd154112021-10-08 11:21:14 +0200195
196# libc
197add_library(c STATIC IMPORTED)
Mark Dykese9db8172022-07-21 14:10:00 -0500198# We need "freestandig" mode. Ask the compile to do the needed configurations.
199include(${TS_ROOT}/tools/cmake/compiler/GCC.cmake)
200compiler_set_freestanding(TARGET c)
Gyorgy Szing51f45d22021-12-08 00:44:18 +0000201set_property(TARGET c PROPERTY IMPORTED_LOCATION "${NEWLIB_LIBC_PATH}")
Mark Dykese9db8172022-07-21 14:10:00 -0500202target_compile_definitions(c INTERFACE ENABLE_CDEFSH_FIX)
Gyorgy Szing51f45d22021-12-08 00:44:18 +0000203set_property(TARGET c PROPERTY
204 INTERFACE_INCLUDE_DIRECTORIES "${NEWLIB_INSTALL_DIR}/${COMPILER_PREFIX}/include")
Gyorgy Szing309e9712022-02-24 18:35:28 +0100205
206# Make standard library available in the build system.
207add_library(stdlib::c ALIAS c)
Imre Kisdd154112021-10-08 11:21:14 +0200208
209# libnosys
210add_library(nosys STATIC IMPORTED)
Gyorgy Szing51f45d22021-12-08 00:44:18 +0000211set_property(TARGET nosys PROPERTY IMPORTED_LOCATION "${NEWLIB_LIBNOSYS_PATH}")
212set_property(TARGET nosys PROPERTY
213 INTERFACE_INCLUDE_DIRECTORIES "${NEWLIB_INSTALL_DIR}/${COMPILER_PREFIX}/include")
Mark Dykese9db8172022-07-21 14:10:00 -0500214compiler_set_freestanding(TARGET nosys)
Gyorgy Szing693877e2021-12-12 02:51:10 +0100215target_link_libraries(c INTERFACE nosys)