diff --git a/libc/test/CMakeLists.txt b/libc/test/CMakeLists.txt index f22f2b183aca9..0773e9cf15242 100644 --- a/libc/test/CMakeLists.txt +++ b/libc/test/CMakeLists.txt @@ -14,14 +14,14 @@ if(LIBC_TARGET_ARCHITECTURE_IS_GPU AND return() endif() -add_subdirectory(include) -add_subdirectory(src) -add_subdirectory(utils) - if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_BAREMETAL) add_subdirectory(IntegrationTest) endif() +add_subdirectory(include) +add_subdirectory(src) +add_subdirectory(utils) # uses IntegrationTest + if(NOT LLVM_LIBC_FULL_BUILD) return() endif() diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt index 6c99c6735beff..4ad166b8a600c 100644 --- a/libc/test/src/CMakeLists.txt +++ b/libc/test/src/CMakeLists.txt @@ -83,8 +83,7 @@ if(LLVM_RUNTIMES_BUILD OR LIBC_HDRGEN_EXE) return() endif() -set(public_test ${CMAKE_CURRENT_BINARY_DIR}/public_api_test.cpp) - +# Generate api public entrypoints. set(entrypoints_name_list "") foreach(entry IN LISTS TARGET_LLVMLIBC_ENTRYPOINTS) get_target_property(entry_name ${entry} "ENTRYPOINT_NAME") @@ -92,22 +91,30 @@ foreach(entry IN LISTS TARGET_LLVMLIBC_ENTRYPOINTS) endforeach() # TODO: Remove these when they are added to the TableGen. -list(REMOVE_ITEM entrypoints_name_list "__assert_fail" "__errno_location") -list(TRANSFORM entrypoints_name_list PREPEND "-e=") +list(REMOVE_ITEM entrypoints_name_list "prctl" "getauxval" "__stack_chk_fail") +string(REPLACE ";" "," entrypoints_name_list "${entrypoints_name_list}") -file(GLOB spec_files ${LIBC_SOURCE_DIR}/spec/*.td) +set(public_entrypoints ${CMAKE_CURRENT_BINARY_DIR}/public_entrypoints.txt) +file(WRITE ${public_entrypoints} "${entrypoints_name_list}") # Generate api test souce code. +set(public_test ${CMAKE_CURRENT_BINARY_DIR}/public_api_test.cpp) +file(GLOB spec_files ${LIBC_SOURCE_DIR}/spec/*.td) add_custom_command( OUTPUT ${public_test} - COMMAND $ -o ${public_test} - ${entrypoints_name_list} - -I ${LIBC_SOURCE_DIR} - ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td - - DEPENDS ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td ${spec_files} - libc-prototype-testgen ${TARGET_PUBLIC_HEADERS} - ${LIBC_TARGET} + COMMAND + "$" + -o ${public_test} + --entrypoints_file ${public_entrypoints} + -I ${LIBC_SOURCE_DIR} + ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td + DEPENDS + ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td + ${spec_files} + ${public_entrypoints} + libc-prototype-testgen + ${TARGET_PUBLIC_HEADERS} + ${LIBC_TARGET} ) add_custom_target(libc-api-test) diff --git a/libc/utils/HdrGen/PrototypeTestGen/CMakeLists.txt b/libc/utils/HdrGen/PrototypeTestGen/CMakeLists.txt index 9e25c21c6b359..331eb70b7e989 100644 --- a/libc/utils/HdrGen/PrototypeTestGen/CMakeLists.txt +++ b/libc/utils/HdrGen/PrototypeTestGen/CMakeLists.txt @@ -1,5 +1,17 @@ +include(TableGen) + +set(LLVM_LINK_COMPONENTS Support) + add_tablegen(libc-prototype-testgen LLVM_LIBC PrototypeTestGen.cpp ) -target_link_libraries(libc-prototype-testgen PRIVATE LibcTableGenUtil) -target_include_directories(libc-prototype-testgen PRIVATE ${LIBC_SOURCE_DIR}) +target_link_libraries(libc-prototype-testgen + PRIVATE + LibcTableGenUtil +) +target_include_directories(libc-prototype-testgen + PRIVATE + ${LIBC_SOURCE_DIR} + ${LLVM_INCLUDE_DIR} + ${LLVM_MAIN_INCLUDE_DIR} +) diff --git a/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp b/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp index 551b97caf81fd..b1f89fbea0256 100644 --- a/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp +++ b/libc/utils/HdrGen/PrototypeTestGen/PrototypeTestGen.cpp @@ -8,16 +8,19 @@ #include "utils/LibcTableGenUtil/APIIndexer.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/TableGen/Main.h" #include "llvm/TableGen/Record.h" namespace { -llvm::cl::list - EntrypointNamesOption("e", llvm::cl::desc(""), - llvm::cl::OneOrMore); +llvm::cl::opt EntrypointsFilename( + "entrypoints_file", + llvm::cl::desc("file containing the comma separated list of entrypoints"), + llvm::cl::Required); } // anonymous namespace @@ -25,7 +28,13 @@ bool TestGeneratorMain(llvm::raw_ostream &OS, llvm::RecordKeeper &records) { OS << "#include \"src/__support/CPP/type_traits.h\"\n"; llvm_libc::APIIndexer G(records); std::unordered_set headerFileSet; - for (const auto &entrypoint : EntrypointNamesOption) { + + auto Entrypoints = llvm::MemoryBuffer::getFile(EntrypointsFilename); + + std::vector entrypoints; + for (auto entrypoint : llvm::split((*Entrypoints)->getBuffer(), ',')) + entrypoints.push_back(entrypoint.str()); + for (auto entrypoint : entrypoints) { if (entrypoint == "errno") continue; auto match = G.FunctionToHeaderMap.find(entrypoint); @@ -48,7 +57,7 @@ bool TestGeneratorMain(llvm::raw_ostream &OS, llvm::RecordKeeper &records) { OS << '\n'; OS << "extern \"C\" int main() {\n"; - for (const auto &entrypoint : EntrypointNamesOption) { + for (const auto &entrypoint : entrypoints) { if (entrypoint == "errno") continue; auto match = G.FunctionSpecMap.find(entrypoint); @@ -91,9 +100,17 @@ bool TestGeneratorMain(llvm::raw_ostream &OS, llvm::RecordKeeper &records) { << " prototype in TableGen does not match public header" << '"'; OS << ");\n"; } + OS << '\n'; + OS << " // Check that all entrypoints are present in the binary"; + OS << " uintptr_t check = 0;\n"; + for (const auto &entrypoint : entrypoints) { + if (entrypoint == "errno") + continue; + OS << " check += reinterpret_cast(&" << entrypoint << ");\n"; + } OS << '\n'; - OS << " return 0;\n"; + OS << " return check != 0 ? 0 : 1;\n"; OS << "}\n\n"; return false;