diff --git a/libc/src/stdio/fprintf.cpp b/libc/src/stdio/fprintf.cpp --- a/libc/src/stdio/fprintf.cpp +++ b/libc/src/stdio/fprintf.cpp @@ -8,7 +8,6 @@ #include "src/stdio/fprintf.h" -#include "src/__support/File/file.h" #include "src/__support/arg_list.h" #include "src/stdio/printf_core/vfprintf_internal.h" @@ -18,6 +17,7 @@ namespace __llvm_libc { #ifndef LIBC_COPT_PRINTF_USE_SYSTEM_FILE +#include "src/__support/File/file.h" using FileT = __llvm_libc::File; #else // defined(LIBC_COPT_PRINTF_USE_SYSTEM_FILE) using FileT = ::FILE; diff --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt --- a/libc/test/src/stdio/CMakeLists.txt +++ b/libc/test/src/stdio/CMakeLists.txt @@ -1,5 +1,13 @@ add_libc_testsuite(libc_stdio_unittests) +add_header_library( + testdata_path_util + HDRS + testdata_path_util.h + DEPENDS + libc.include.stdlib +) + add_libc_unittest( fileop_test SUITE diff --git a/libc/test/src/stdio/fprintf_test.cpp b/libc/test/src/stdio/fprintf_test.cpp --- a/libc/test/src/stdio/fprintf_test.cpp +++ b/libc/test/src/stdio/fprintf_test.cpp @@ -17,6 +17,8 @@ #include "test/UnitTest/Test.h" +#include "test/src/stdio/testdata_path_util.h" + #include namespace printf_test { @@ -34,8 +36,12 @@ } // namespace printf_test TEST(LlvmLibcFPrintfTest, WriteToFile) { - constexpr char FILENAME[] = "testdata/fprintf_output.test"; - ::FILE *file = printf_test::fopen(FILENAME, "w"); + constexpr char FILENAME[] = "fprintf_output.test"; + char FILE_PATH[1024] = {'\0'}; + + write_file_path(FILE_PATH, FILENAME); + + ::FILE *file = printf_test::fopen(FILE_PATH, "w"); ASSERT_FALSE(file == nullptr); int written; @@ -55,7 +61,7 @@ ASSERT_EQ(0, printf_test::fclose(file)); - file = printf_test::fopen(FILENAME, "r"); + file = printf_test::fopen(FILE_PATH, "r"); ASSERT_FALSE(file == nullptr); char data[50]; diff --git a/libc/test/src/stdio/testdata_path_util.h b/libc/test/src/stdio/testdata_path_util.h new file mode 100644 --- /dev/null +++ b/libc/test/src/stdio/testdata_path_util.h @@ -0,0 +1,35 @@ +//===-- Utilities for finding the testdata path ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +// This is to support building with Bazel. +static const char *const UNDECLARED_OUTPUTS_PATH = + getenv("TEST_UNDECLARED_OUTPUTS_DIR"); + +constexpr char DEFAULT_DIR[] = "testdata/"; + +inline void concat_path(char *output, const char *path, const char *filename) { + size_t i = 0; + for (; path[i] != '\0'; ++i) { + output[i] = path[i]; + } + for (size_t j = 0; filename[j] != '\0'; ++i, ++j) { + output[i] = filename[j]; + } +} + +inline void write_file_path(char *output, const char *filename) { + if (UNDECLARED_OUTPUTS_PATH == nullptr || + UNDECLARED_OUTPUTS_PATH[0] == '\0') { + concat_path(output, DEFAULT_DIR, filename); + } else { + concat_path(output, UNDECLARED_OUTPUTS_PATH, filename); + } +} diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -8,6 +8,7 @@ "libc_function", "libc_math_function", "libc_support_library", + "PRINTF_COPTS", ) load(":platforms.bzl", "PLATFORM_CPU_ARM64", "PLATFORM_CPU_X86_64") load("@bazel_skylib//lib:selects.bzl", "selects") @@ -152,6 +153,14 @@ ], ) +libc_support_library( + name = "__support_cpp_expected", + hdrs = ["src/__support/CPP/expected.h"], + deps = [ + ":libc_root", + ], +) + libc_support_library( name = "__support_cpp_functional", hdrs = ["src/__support/CPP/functional.h"], @@ -164,6 +173,17 @@ deps = [":libc_root"], ) + +libc_support_library( + name = "__support_cpp_new", + hdrs = ["src/__support/CPP/new.h"], + srcs = ["src/__support/CPP/new.cpp"], + deps = [ + ":libc_root", + ":__support_common", + ], +) + libc_support_library( name = "__support_cpp_optional", hdrs = ["src/__support/CPP/optional.h"], @@ -223,6 +243,16 @@ ], ) +libc_support_library( + name = "__support_error_or", + hdrs = ["src/__support/error_or.h"], + deps = [ + ":libc_root", + ":__support_cpp_expected", + ":__support_common", + ], +) + libc_support_library( name = "__support_float_to_string", hdrs = [ @@ -376,6 +406,20 @@ ], ) +libc_support_library( + name = "__support_file_file", + hdrs = ["src/__support/File/file.h"], + srcs = ["src/__support/File/file.cpp"], + deps = [ + ":libc_root", + ":__support_cpp_new", + ":__support_error_or", + ":__support_cpp_span", + ":__support_threads_mutex", + ":errno", + ], +) + libc_support_library( name = "__support_named_pair", hdrs = ["src/__support/named_pair.h"], @@ -678,6 +722,22 @@ ], ) +libc_support_library( + name = "__support_threads_mutex", + hdrs = [ + "src/__support/threads/mutex.h", + "src/__support/threads/mutex_common.h", + ], + textual_hdrs = [ + "src/__support/threads/linux/mutex.h", + "src/__support/threads/linux/futex_word.h", + ], + deps = [ + ":libc_root", + ":__support_cpp_atomic", + ":__support_osutil_syscall", + ], +) ############################### errno targets ################################ @@ -2061,6 +2121,7 @@ ":__support_fputil_fp_bits", ":libc_root", ], + copts = PRINTF_COPTS, ) libc_support_library( @@ -2069,6 +2130,7 @@ deps = [ ":libc_root", ], + copts = PRINTF_COPTS, ) @@ -2090,6 +2152,7 @@ ":__support_common", ":libc_root", ], + copts = PRINTF_COPTS, ) # Only used for testing. @@ -2111,7 +2174,7 @@ ":__support_common", ":libc_root", ], - copts = ["-DLIBC_COPT_MOCK_ARG_LIST"], + copts = PRINTF_COPTS + ["-DLIBC_COPT_MOCK_ARG_LIST"], ) libc_support_library( @@ -2124,6 +2187,19 @@ ":printf_core_structs", ":libc_root", ], + copts = PRINTF_COPTS, +) + +libc_support_library( + name = "printf_file_writer", + hdrs = ["src/stdio/printf_core/file_writer.h"], + deps = [ + ":__support_cpp_string_view", + ":__support_file_file", + ":printf_core_structs", + ":libc_root", + ], + copts = PRINTF_COPTS, ) libc_support_library( @@ -2134,6 +2210,7 @@ ":__support_cpp_string_view", ":libc_root", ], + copts = PRINTF_COPTS, ) libc_support_library( @@ -2168,6 +2245,7 @@ ":__support_common", ":libc_root", ], + copts = PRINTF_COPTS, ) libc_support_library( @@ -2182,6 +2260,7 @@ ":__support_arg_list", ":libc_root", ], + copts = PRINTF_COPTS, ) libc_function( @@ -2195,6 +2274,7 @@ ":printf_writer", ":errno", ], + copts = PRINTF_COPTS, ) libc_function( @@ -2208,4 +2288,44 @@ ":printf_writer", ":errno", ], + copts = PRINTF_COPTS, +) + +libc_support_library( + name = "vfprintf_internal", + hdrs = ["src/stdio/printf_core/vfprintf_internal.h"], + deps = [ + ":__support_arg_list", + ":__support_file_file", + ":__support_macros_attributes", + ":printf_main", + ":printf_file_writer", + ":printf_writer", + ], + copts = PRINTF_COPTS, +) + +libc_function( + name = "printf", + srcs = ["src/stdio/printf.cpp"], + hdrs = ["src/stdio/printf.h"], + deps = [ + ":__support_arg_list", + ":vfprintf_internal", + ":errno", + ], + copts = PRINTF_COPTS, +) + + +libc_function( + name = "fprintf", + srcs = ["src/stdio/fprintf.cpp"], + hdrs = ["src/stdio/fprintf.h"], + deps = [ + ":__support_arg_list", + ":vfprintf_internal", + ":errno", + ], + copts = PRINTF_COPTS, ) diff --git a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl --- a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl +++ b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl @@ -10,6 +10,12 @@ LIBC_ROOT_TARGET = ":libc_root" INTERNAL_SUFFIX = ".__internal__" +PRINTF_COPTS = [ + "-DLIBC_COPT_PRINTF_USE_SYSTEM_FILE", + "-DLIBC_COPT_PRINTF_DISABLE_INDEX_MODE", + "-DLIBC_COPT_PRINTF_DISABLE_WRITE_INT", +] + def _libc_library(name, copts = None, **kwargs): """Internal macro to serve as a base for all other libc library rules. @@ -23,7 +29,7 @@ # We want all libc sources to be compiled with "hidden" visibility. # The public symbols will be given "default" visibility explicitly. # See src/__support/common.h for more information. - copts.append("-fvisibility=hidden") + copts = copts + ["-fvisibility=hidden"] native.cc_library( name = name, copts = copts, @@ -65,11 +71,11 @@ **kwargs: Other attributes relevant for a cc_library. For example, deps. """ deps = deps or [] - deps.append(LIBC_ROOT_TARGET) + # We use the explicit equals pattern here because append and += mutate the + # original list, where this creates a new list and stores it in deps. + deps = deps + [LIBC_ROOT_TARGET] copts = copts or [] - copts.append("-O3") - copts.append("-fno-builtin") - copts.append("-fno-lax-vector-conversions") + copts = copts + ["-O3", "-fno-builtin", "-fno-lax-vector-conversions"] # We compile the code twice, the first target is suffixed with ".__internal__" and contains the # C++ functions in the "__llvm_libc" namespace. This allows us to test the function in the @@ -87,9 +93,9 @@ func_attrs = ["__attribute__((visibility(\"default\")))"] if weak: - func_attrs.append("__attribute__((weak))") + func_attrs = func_attrs + ["__attribute__((weak))"] local_defines = local_defines or ["LIBC_COPT_PUBLIC_PACKAGING"] - local_defines.append("LLVM_LIBC_FUNCTION_ATTR='%s'" % " ".join(func_attrs)) + local_defines = local_defines + ["LLVM_LIBC_FUNCTION_ATTR='%s'" % " ".join(func_attrs)] _libc_library( name = name, srcs = srcs, diff --git a/utils/bazel/llvm-project-overlay/libc/test/libc_test_rules.bzl b/utils/bazel/llvm-project-overlay/libc/test/libc_test_rules.bzl --- a/utils/bazel/llvm-project-overlay/libc/test/libc_test_rules.bzl +++ b/utils/bazel/llvm-project-overlay/libc/test/libc_test_rules.bzl @@ -14,7 +14,7 @@ load("//libc:libc_build_rules.bzl", "INTERNAL_SUFFIX") -def libc_test(name, srcs, libc_function_deps, deps = [], **kwargs): +def libc_test(name, srcs, libc_function_deps, deps = [], output_file = "", **kwargs): """Add target for a libc test. Args: diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/stdio/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/stdio/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/libc/test/src/stdio/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/src/stdio/BUILD.bazel @@ -5,11 +5,17 @@ # Tests for LLVM libc stdio.h functions. load("//libc/test:libc_test_rules.bzl", "libc_test") +load("//libc:libc_build_rules.bzl", "PRINTF_COPTS") package(default_visibility = ["//visibility:public"]) licenses(["notice"]) +cc_library( + name = "testdata_path_util", + hdrs = ["testdata_path_util.h"], +) + libc_test( name = "printf_parser_test", srcs = ["printf_core/parser_test.cpp"], @@ -24,6 +30,7 @@ "//libc/utils/testutils:libc_test_utils", "//libc/test/UnitTest:printf_matcher", ], + copts = PRINTF_COPTS, ) libc_test( @@ -38,6 +45,7 @@ "//libc:__support_cpp_string_view", "//libc:__support_arg_list", ], + copts = PRINTF_COPTS, ) libc_test( @@ -53,6 +61,7 @@ "//libc:__support_cpp_string_view", "//libc:__support_arg_list", ], + copts = PRINTF_COPTS, ) libc_test( @@ -66,6 +75,7 @@ "//libc:__support_fputil_platform_defs", "//libc/utils/testutils:libc_test_utils", ], + copts = PRINTF_COPTS, ) libc_test( @@ -74,4 +84,26 @@ libc_function_deps = [ "//libc:snprintf", ], + copts = PRINTF_COPTS, +) + +libc_test( + name = "printf_test", + srcs = ["printf_test.cpp"], + libc_function_deps = [ + "//libc:printf", + ], + copts = PRINTF_COPTS, +) + +libc_test( + name = "fprintf_test", + srcs = ["fprintf_test.cpp"], + libc_function_deps = [ + "//libc:fprintf", + ], + deps = [ + ":testdata_path_util", + ], + copts = PRINTF_COPTS, )