[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
This commit is contained in:
Siva Chandra Reddy 2020-06-09 00:31:48 -07:00
parent 01e64c9712
commit fd3295fb6f
10 changed files with 106 additions and 19 deletions

View File

@ -68,6 +68,22 @@ include(LLVMLibCCheckCpuFeatures)
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)

View File

@ -86,6 +86,23 @@ function(add_entrypoint_object target_name)
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.

View File

@ -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 @@ function(get_object_files_for_test result)
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 @@ function(get_object_files_for_test result)
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 @@ function(add_libc_unittest target_name)
"'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 @@ function(add_libc_unittest target_name)
)
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}

View File

@ -1,4 +1,4 @@
set(LIBC_ENTRYPOINTS
set(TARGET_LIBC_ENTRYPOINTS
# assert.h entrypoints
libc.src.assert.__assert_fail
@ -43,7 +43,7 @@ set(LIBC_ENTRYPOINTS
libc.src.unistd.write
)
set(LIBM_ENTRYPOINTS
set(TARGET_LIBM_ENTRYPOINTS
# math.h entrypoints
libc.src.math.ceil
libc.src.math.ceilf

View File

@ -1,4 +1,4 @@
set(PUBLIC_HEADERS
set(TARGET_PUBLIC_HEADERS
libc.include.assert_h
libc.include.errno
libc.include.math

View File

@ -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(

View File

@ -56,6 +56,11 @@ function(add_loader_object name)
)
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(

View File

@ -38,7 +38,7 @@ function(add_loader_test target_name)
)
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(

View File

@ -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

View File

@ -9,13 +9,10 @@ add_subdirectory(sys)
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()