[libc] Skip entrypoints not present in the entrypoints list.
Summary:
If a test depends on a skipped entrypoint, then the test is also
skipped. This setup will be useful as we gradually add support for
more operating systems and target architectures.
Reviewers: asteinhauser
Differential Revision: https://reviews.llvm.org/D81489
GitOrigin-RevId: fd3295fb6f981a5c030d7540b9eda67f9c723e0f
diff --git a/CMakeLists.txt b/CMakeLists.txt
index df0448b..b774eac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -68,6 +68,22 @@
add_subdirectory(include)
add_subdirectory(config)
+
+include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/entrypoints.txt")
+include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/headers.txt")
+
+set(TARGET_ENTRYPOINT_NAME_LIST "")
+foreach(entrypoint IN LISTS TARGET_LIBC_ENTRYPOINTS TARGET_LIBM_ENTRYPOINTS)
+ string(FIND ${entrypoint} "." last_dot_loc REVERSE)
+ if(${last_dot_loc} EQUAL -1)
+ message(FATAL "Invalid entrypoint target name ${entrypoint}; Expected a '.' "
+ "(dot) in the name.")
+ endif()
+ math(EXPR name_loc "${last_dot_loc} + 1")
+ string(SUBSTRING ${entrypoint} ${name_loc} -1 entrypoint_name)
+ list(APPEND TARGET_ENTRYPOINT_NAME_LIST ${entrypoint_name})
+endforeach()
+
add_subdirectory(src)
add_subdirectory(utils)
diff --git a/cmake/modules/LLVMLibCObjectRules.cmake b/cmake/modules/LLVMLibCObjectRules.cmake
index d1d098d..32900d8 100644
--- a/cmake/modules/LLVMLibCObjectRules.cmake
+++ b/cmake/modules/LLVMLibCObjectRules.cmake
@@ -86,6 +86,23 @@
set(entrypoint_name ${ADD_ENTRYPOINT_OBJ_NAME})
endif()
+ list(FIND TARGET_ENTRYPOINT_NAME_LIST ${entrypoint_name} entrypoint_name_index)
+ if(${entrypoint_name_index} EQUAL -1)
+ add_custom_target(${fq_target_name})
+ set_target_properties(
+ ${fq_target_name}
+ PROPERTIES
+ "ENTRYPOINT_NAME" ${entrypoint_name}
+ "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE}
+ "OBJECT_FILE" ""
+ "OBJECT_FILE_RAW" ""
+ "DEPS" ""
+ "SKIPPED" "YES"
+ )
+ message(STATUS "Skipping libc entrypoint ${fq_target_name}.")
+ return()
+ endif()
+
if(ADD_ENTRYPOINT_OBJ_ALIAS)
# Alias targets help one add aliases to other entrypoint object targets.
# One can use alias targets setup OS/machine independent entrypoint targets.
diff --git a/cmake/modules/LLVMLibCTestRules.cmake b/cmake/modules/LLVMLibCTestRules.cmake
index 831cbc0..e33f528 100644
--- a/cmake/modules/LLVMLibCTestRules.cmake
+++ b/cmake/modules/LLVMLibCTestRules.cmake
@@ -3,12 +3,18 @@
# recursively produced by "add_entrypoint_object" and "add_object_library"
# targets.
# Usage:
-# get_object_files_for_test(<result var> <target0> [<target1> ...])
+# get_object_files_for_test(<result var>
+# <skipped_entrypoints_var>
+# <target0> [<target1> ...])
#
+# The list of object files is collected in <result_var>.
+# If skipped entrypoints were found, then <skipped_entrypoints_var> is
+# set to a true value.
# targetN is either an "add_entrypoint_target" target or an
# "add_object_library" target.
-function(get_object_files_for_test result)
+function(get_object_files_for_test result skipped_entrypoints_list)
set(object_files "")
+ set(skipped_list "")
foreach(dep IN LISTS ARGN)
get_target_property(dep_type ${dep} "TARGET_TYPE")
if(NOT dep_type)
@@ -23,6 +29,11 @@
list(APPEND object_files ${dep_object_files})
endif()
elseif(${dep_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE})
+ get_target_property(is_skipped ${dep} "SKIPPED")
+ if(is_skipped)
+ list(APPEND skipped_list ${dep})
+ continue()
+ endif()
get_target_property(object_file_raw ${dep} "OBJECT_FILE_RAW")
if(object_file_raw)
list(APPEND object_files ${object_file_raw})
@@ -30,11 +41,17 @@
endif()
get_target_property(indirect_deps ${dep} "DEPS")
- get_object_files_for_test(indirect_objfiles ${indirect_deps})
+ get_object_files_for_test(
+ indirect_objfiles indirect_skipped_list ${indirect_deps})
list(APPEND object_files ${indirect_objfiles})
+ if(indirect_skipped_list)
+ list(APPEND skipped_list ${indirect_skipped_list})
+ endif()
endforeach(dep)
list(REMOVE_DUPLICATES object_files)
set(${result} ${object_files} PARENT_SCOPE)
+ list(REMOVE_DUPLICATES skipped_list)
+ set(${skipped_entrypoints_list} ${skipped_list} PARENT_SCOPE)
endfunction(get_object_files_for_test)
# Rule to add a libc unittest.
@@ -68,8 +85,43 @@
"'add_entrypoint_object' targets.")
endif()
-
get_fq_target_name(${target_name} fq_target_name)
+ get_fq_deps_list(fq_deps_list ${LIBC_UNITTEST_DEPENDS})
+ get_object_files_for_test(
+ link_object_files skipped_entrypoints_list ${fq_deps_list})
+ if(skipped_entrypoints_list)
+ # If a test is OS/target machine independent, it has to be skipped if the
+ # OS/target machine combination does not provide any dependent entrypoints.
+ # If a test is OS/target machine specific, then such a test will live is a
+ # OS/target machine specific directory and will be skipped at the directory
+ # level if required.
+ #
+ # There can potentially be a setup like this: A unittest is setup for a
+ # OS/target machine independent object library, which in turn depends on a
+ # machine specific object library. Such a test would be testing internals of
+ # the libc and it is assumed that they will be rare in practice. So, they
+ # can be skipped in the corresponding CMake files using platform specific
+ # logic. This pattern is followed in the loader tests for example.
+ #
+ # Another pattern that is present currently is to detect machine
+ # capabilities and add entrypoints and tests accordingly. That approach is
+ # much lower level approach and is independent of the kind of skipping that
+ # is happening here at the entrypoint level.
+
+ set(msg "Skipping unittest ${fq_target_name} as it has missing deps: "
+ "${skipped_entrypoints_list}.")
+ message(STATUS ${msg})
+ add_custom_target(${fq_target_name})
+
+ # A post build custom command is used to avoid running the command always.
+ add_custom_command(
+ TARGET ${fq_target_name}
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo ${msg}
+ )
+ return()
+ endif()
+
add_executable(
${fq_target_name}
EXCLUDE_FROM_ALL
@@ -90,8 +142,6 @@
)
endif()
- get_fq_deps_list(fq_deps_list ${LIBC_UNITTEST_DEPENDS})
- get_object_files_for_test(link_object_files ${fq_deps_list})
target_link_libraries(${fq_target_name} PRIVATE ${link_object_files})
set_target_properties(${fq_target_name}
diff --git a/config/linux/x86_64/entrypoints.txt b/config/linux/x86_64/entrypoints.txt
index 9e93ee5..47329d2 100644
--- a/config/linux/x86_64/entrypoints.txt
+++ b/config/linux/x86_64/entrypoints.txt
@@ -1,4 +1,4 @@
-set(LIBC_ENTRYPOINTS
+set(TARGET_LIBC_ENTRYPOINTS
# assert.h entrypoints
libc.src.assert.__assert_fail
@@ -43,7 +43,7 @@
libc.src.unistd.write
)
-set(LIBM_ENTRYPOINTS
+set(TARGET_LIBM_ENTRYPOINTS
# math.h entrypoints
libc.src.math.ceil
libc.src.math.ceilf
diff --git a/config/linux/x86_64/headers.txt b/config/linux/x86_64/headers.txt
index 8c7d71e..b44681a 100644
--- a/config/linux/x86_64/headers.txt
+++ b/config/linux/x86_64/headers.txt
@@ -1,4 +1,4 @@
-set(PUBLIC_HEADERS
+set(TARGET_PUBLIC_HEADERS
libc.include.assert_h
libc.include.errno
libc.include.math
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index deae56e..1634053 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -1,16 +1,13 @@
-include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/entrypoints.txt")
-include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/headers.txt")
-
add_entrypoint_library(
llvmlibc
DEPENDS
- ${LIBC_ENTRYPOINTS}
+ ${TARGET_LIBC_ENTRYPOINTS}
)
add_entrypoint_library(
llvmlibm
DEPENDS
- ${LIBM_ENTRYPOINTS}
+ ${TARGET_LIBM_ENTRYPOINTS}
)
add_redirector_library(
diff --git a/loader/linux/CMakeLists.txt b/loader/linux/CMakeLists.txt
index b972f72..5cb184a 100644
--- a/loader/linux/CMakeLists.txt
+++ b/loader/linux/CMakeLists.txt
@@ -56,6 +56,11 @@
)
endfunction()
+if(NOT (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_MACHINE}))
+ message(STATUS "Skipping loader for target machine ${LIBC_TARGET_MACHINE}")
+ return()
+endif()
+
add_subdirectory(${LIBC_TARGET_MACHINE})
add_loader_object(
diff --git a/test/loader/CMakeLists.txt b/test/loader/CMakeLists.txt
index 56b4c34..a38d388 100644
--- a/test/loader/CMakeLists.txt
+++ b/test/loader/CMakeLists.txt
@@ -38,7 +38,7 @@
)
get_fq_deps_list(fq_deps_list ${ADD_LOADER_TEST_DEPENDS})
- get_object_files_for_test(link_object_files ${fq_deps_list})
+ get_object_files_for_test(link_object_files has_skipped_entrypoint_list ${fq_deps_list})
target_link_libraries(${fq_target_name} ${link_object_files})
target_link_options(
diff --git a/test/loader/linux/CMakeLists.txt b/test/loader/linux/CMakeLists.txt
index 887f9ef..1f47b2c 100644
--- a/test/loader/linux/CMakeLists.txt
+++ b/test/loader/linux/CMakeLists.txt
@@ -1,3 +1,8 @@
+if(NOT (EXISTS ${LIBC_SOURCE_DIR}/loader/linux/${LIBC_TARGET_MACHINE}))
+ message("Skipping loader tests for target machine ${LIBC_TARGET_MACHINE}.")
+ return()
+endif()
+
add_loader_test(
loader_args_test
SRC
diff --git a/test/src/CMakeLists.txt b/test/src/CMakeLists.txt
index c6bcdae..3dc9394 100644
--- a/test/src/CMakeLists.txt
+++ b/test/src/CMakeLists.txt
@@ -9,13 +9,10 @@
add_subdirectory(threads)
add_subdirectory(unistd)
-include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/entrypoints.txt")
-include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/headers.txt")
-
set(public_test ${CMAKE_CURRENT_BINARY_DIR}/public_integration_test.cpp)
set(entrypoints_name_list "")
-foreach(entry IN LISTS LIBC_ENTRYPOINTS LIBM_ENTRYPOINTS)
+foreach(entry IN LISTS TARGET_LIBC_ENTRYPOINTS TARGET_LIBM_ENTRYPOINTS)
get_target_property(entry_name ${entry} "ENTRYPOINT_NAME")
list(APPEND entrypoints_name_list ${entry_name})
endforeach()