1# 2# SPDX-License-Identifier: BSD-3-Clause 3# 4# Copyright © 2022 Keith Packard 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 13# 2. Redistributions in binary form must reproduce the above 14# copyright notice, this list of conditions and the following 15# disclaimer in the documentation and/or other materials provided 16# with the distribution. 17# 18# 3. Neither the name of the copyright holder nor the names of its 19# contributors may be used to endorse or promote products derived 20# from this software without specific prior written permission. 21# 22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 33# OF THE POSSIBILITY OF SUCH DAMAGE. 34# 35 36# Add sources to libc, eliding any duplicate basenames 37function(picolibc_sources_flags flags) 38 39 # Get current sources 40 get_property(current_sources_real TARGET c PROPERTY SOURCES) 41 get_property(current_sources_fake TARGET c PROPERTY SOURCES_FAKE) 42 set(current_sources ${current_sources_real} ${current_sources_fake}) 43 set(sources ${ARGN}) 44 45 foreach(source IN LISTS ARGN) 46 # Compare desired addition to existing sources using basenames 47 get_filename_component(source_base "${source}" NAME_WLE) 48 foreach(current IN LISTS current_sources) 49 get_filename_component(current_base "${current}" NAME_WLE) 50 if("${source_base}" STREQUAL "${current_base}") 51 list(REMOVE_ITEM sources "${source}") 52 endif() 53 endforeach() 54 endforeach() 55 56 # Add all files that aren't duplicated 57 target_sources(c PRIVATE ${sources}) 58 59 # Set flags if specified 60 if(flags) 61 foreach(flag ${flags}) 62 foreach(source ${sources}) 63 set_property(SOURCE ${source} 64 TARGET_DIRECTORY c 65 APPEND PROPERTY COMPILE_OPTIONS ${flag}) 66 endforeach() 67 endforeach() 68 endif() 69endfunction() 70 71function(picolibc_sources) 72 picolibc_sources_flags(0 ${ARGN}) 73endfunction() 74 75function(picolibc_sources_fake) 76 get_property(current_sources_fake TARGET c PROPERTY SOURCES_FAKE) 77 list(APPEND current_sources_fake ${ARGN}) 78 set_property(TARGET c PROPERTY SOURCES_FAKE ${current_sources_fake}) 79endfunction() 80 81function(picolibc_headers subdir) 82 83 # Get current headers 84 get_property(current_headers GLOBAL PROPERTY PICOLIBC_HEADERS) 85 86 set(orig_headers ${ARGN}) 87 88 foreach(header IN LISTS ARGN) 89 set(rel_header "${subdir}/${header}") 90 set(include 1) 91 foreach(current IN LISTS current_headers) 92 if("${rel_header}" STREQUAL "${current}") 93 list(REMOVE_ITEM orig_headers "${header}") 94 set(include 0) 95 endif() 96 endforeach() 97 if(include) 98 list(APPEND current_headers "${rel_header}") 99 configure_file("${header}" "${PROJECT_BINARY_DIR}/picolibc/include/${rel_header}") 100 endif() 101 endforeach() 102 set_property(GLOBAL PROPERTY PICOLIBC_HEADERS ${current_headers}) 103 install(FILES ${orig_headers} DESTINATION "include/${subdir}") 104endfunction() 105 106function(_picolibc_supported_compile_options var) 107 set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 108 foreach(flag ${ARGN}) 109 string(MAKE_C_IDENTIFIER ${flag} flag_under) 110 try_compile(${flag_under} "${PROJECT_BINARY_DIR}" 111 "${CMAKE_CURRENT_SOURCE_DIR}/cmake/simple-main.c" 112 COMPILE_DEFINITIONS "${PICOLIBC_TEST_COMPILE_OPTIONS};${PICOLIBC_FLAG_OPTIONS};${flag}" 113 ) 114 if(${${flag_under}}) 115 list(APPEND options ${flag}) 116 endif() 117 endforeach() 118 set(${var} ${options} PARENT_SCOPE) 119endfunction() 120 121# These flags are needed to generate errors for invalid command line flags 122# instead of just warnings 123_picolibc_supported_compile_options(PICOLIBC_FLAG_OPTIONS 124 -Werror=missing-declarations 125 -Werror=unknown-attributes 126 -Werror=attributes 127 -Werror=unsupported-floating-point-opt 128 -Werror=ignored-optimization-argument 129 -Wno-unused-command-line-argument 130 ) 131 132function(picolibc_supported_compile_options) 133 _picolibc_supported_compile_options(options ${ARGN}) 134 set(PICOLIBC_COMPILE_OPTIONS ${PICOLIBC_COMPILE_OPTIONS} ${options} PARENT_SCOPE) 135endfunction() 136 137function(picolibc_flag flag) 138 139 string(REPLACE "_" "-" flag_dash ${flag}) 140 string(REGEX REPLACE "^-" "" flag_trim ${flag_dash}) 141 string(TOLOWER ${flag_trim} flag_lower) 142 set(flag_file "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${flag_lower}.c") 143 144 if (NOT EXISTS "${flag_file}") 145 message(ERROR " Missing compiler test file ${flag_file}") 146 endif() 147 148 set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 149 150 try_compile(${flag} "${PROJECT_BINARY_DIR}" "${flag_file}" 151 COMPILE_DEFINITIONS "${PICOLIBC_FLAG_OPTIONS}" 152 ) 153 154 if (${flag}) 155 set(${flag} ${flag} PARENT_SCOPE) 156 endif() 157endfunction() 158 159