summaryrefslogtreecommitdiff
path: root/cmake/Modules/CompilerRTUtils.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/Modules/CompilerRTUtils.cmake')
-rw-r--r--cmake/Modules/CompilerRTUtils.cmake29
1 files changed, 29 insertions, 0 deletions
diff --git a/cmake/Modules/CompilerRTUtils.cmake b/cmake/Modules/CompilerRTUtils.cmake
index 36df49fcc..63b225260 100644
--- a/cmake/Modules/CompilerRTUtils.cmake
+++ b/cmake/Modules/CompilerRTUtils.cmake
@@ -270,3 +270,32 @@ macro(construct_compiler_rt_default_triple)
set(COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE FALSE)
endif()
endmacro()
+
+# Filter out generic versions of routines that are re-implemented in
+# architecture specific manner. This prevents multiple definitions of the
+# same symbols, making the symbol selection non-deterministic.
+function(filter_builtin_sources output_var exclude_or_include excluded_list)
+ if(exclude_or_include STREQUAL "EXCLUDE")
+ set(filter_action GREATER)
+ set(filter_value -1)
+ elseif(exclude_or_include STREQUAL "INCLUDE")
+ set(filter_action LESS)
+ set(filter_value 0)
+ else()
+ message(FATAL_ERROR "filter_builtin_sources called without EXCLUDE|INCLUDE")
+ endif()
+
+ set(intermediate ${ARGN})
+ foreach (_file ${intermediate})
+ get_filename_component(_name_we ${_file} NAME_WE)
+ list(FIND ${excluded_list} ${_name_we} _found)
+ if(_found ${filter_action} ${filter_value})
+ list(REMOVE_ITEM intermediate ${_file})
+ elseif(${_file} MATCHES ".*/.*\\.S" OR ${_file} MATCHES ".*/.*\\.c")
+ get_filename_component(_name ${_file} NAME)
+ string(REPLACE ".S" ".c" _cname "${_name}")
+ list(REMOVE_ITEM intermediate ${_cname})
+ endif ()
+ endforeach ()
+ set(${output_var} ${intermediate} PARENT_SCOPE)
+endfunction()