Merge "Collect libc++ headers that have no file name extensions" am: 462b91aae1
Original change: https://android-review.googlesource.com/c/platform/development/+/2473566 Change-Id: Ie89f023c62b1dc45a6eb921aa90fe321c810533f Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -29,13 +29,32 @@ namespace utils {
|
||||
static const std::vector<std::string> header_extensions{
|
||||
".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"};
|
||||
|
||||
static bool HasHeaderExtension(llvm::StringRef &file_name) {
|
||||
static const std::vector<std::string> libcxx_include_dir{"libcxx", "include"};
|
||||
|
||||
static bool HasHeaderExtension(llvm::StringRef file_name) {
|
||||
return std::find_if(header_extensions.begin(), header_extensions.end(),
|
||||
[file_name](const std::string &e) {
|
||||
return file_name.endswith(e);
|
||||
}) != header_extensions.end();
|
||||
}
|
||||
|
||||
static bool PathEndsWith(llvm::StringRef path,
|
||||
const std::vector<std::string> &suffix) {
|
||||
auto path_it = llvm::sys::path::rbegin(path);
|
||||
auto suffix_it = suffix.rbegin();
|
||||
while (suffix_it != suffix.rend()) {
|
||||
if (path_it == llvm::sys::path::rend(path)) {
|
||||
return false;
|
||||
}
|
||||
if (*path_it != *suffix_it) {
|
||||
return false;
|
||||
}
|
||||
++path_it;
|
||||
++suffix_it;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string GetCwd() {
|
||||
llvm::SmallString<256> cwd;
|
||||
if (llvm::sys::fs::current_path(cwd)) {
|
||||
@@ -117,6 +136,11 @@ std::string NormalizePath(std::string_view path, const RootDirs &root_dirs) {
|
||||
static bool CollectExportedHeaderSet(const std::string &dir_name,
|
||||
std::set<std::string> *exported_headers,
|
||||
const RootDirs &root_dirs) {
|
||||
// Bazel creates temporary files in header directories. To avoid race
|
||||
// condition, this function filters headers by name extensions.
|
||||
// An exception is that libc++ headers do not have extensions.
|
||||
bool collect_headers_without_extensions =
|
||||
PathEndsWith(dir_name, libcxx_include_dir);
|
||||
std::error_code ec;
|
||||
llvm::sys::fs::recursive_directory_iterator walker(dir_name, ec);
|
||||
// Default construction - end of directory.
|
||||
@@ -136,7 +160,11 @@ static bool CollectExportedHeaderSet(const std::string &dir_name,
|
||||
walker.no_push();
|
||||
continue;
|
||||
}
|
||||
if (!HasHeaderExtension(file_name)) {
|
||||
if (!file_name.contains(".")) {
|
||||
if (!collect_headers_without_extensions) {
|
||||
continue;
|
||||
}
|
||||
} else if (!HasHeaderExtension(file_name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,14 +24,20 @@ namespace header_checker {
|
||||
namespace utils {
|
||||
|
||||
TEST(SourcePathUtilsTest, CollectAllExportedHeaders) {
|
||||
// Prepare a header directory.
|
||||
TemporaryDir temp_dir;
|
||||
const std::filesystem::path header_dir = temp_dir.path;
|
||||
std::error_code ec;
|
||||
// Prepare a header directory containing links, hidden files, etc.
|
||||
const std::filesystem::path header_dir =
|
||||
std::filesystem::path(temp_dir.path) / "include";
|
||||
ASSERT_TRUE(std::filesystem::create_directory(header_dir, ec));
|
||||
ASSERT_FALSE(ec);
|
||||
|
||||
const std::filesystem::path header = header_dir / "header.h";
|
||||
ASSERT_TRUE(android::base::WriteStringToFile("// test", header));
|
||||
|
||||
std::error_code ec;
|
||||
const std::filesystem::path no_ext_header = header_dir / "header";
|
||||
ASSERT_TRUE(android::base::WriteStringToFile("// test", no_ext_header));
|
||||
|
||||
const std::filesystem::path subdir = header_dir / "subdir";
|
||||
ASSERT_TRUE(std::filesystem::create_directory(subdir, ec));
|
||||
ASSERT_FALSE(ec);
|
||||
@@ -55,15 +61,24 @@ TEST(SourcePathUtilsTest, CollectAllExportedHeaders) {
|
||||
const std::filesystem::path non_header_link = subdir / "header_link.txt";
|
||||
std::filesystem::create_symlink(header, non_header_link, ec);
|
||||
ASSERT_FALSE(ec);
|
||||
// Prepare a header directory like libc++.
|
||||
const std::filesystem::path libcxx_dir =
|
||||
std::filesystem::path(temp_dir.path) / "libcxx" / "include";
|
||||
ASSERT_TRUE(std::filesystem::create_directories(libcxx_dir, ec));
|
||||
ASSERT_FALSE(ec);
|
||||
|
||||
const std::filesystem::path libcxx_header = libcxx_dir / "array";
|
||||
ASSERT_TRUE(android::base::WriteStringToFile("// test", libcxx_header));
|
||||
// Test the function.
|
||||
std::vector<std::string> exported_header_dirs{header_dir};
|
||||
std::vector<RootDir> root_dirs{{header_dir, "include"}};
|
||||
std::vector<std::string> exported_header_dirs{header_dir, libcxx_dir};
|
||||
std::vector<RootDir> root_dirs{{header_dir, "include"},
|
||||
{libcxx_dir, "libcxx"}};
|
||||
std::set<std::string> headers =
|
||||
CollectAllExportedHeaders(exported_header_dirs, root_dirs);
|
||||
|
||||
std::set<std::string> expected_headers{"include/header.h",
|
||||
"include/subdir/header_link.h",
|
||||
"include/subdir_link/header_link.h"};
|
||||
std::set<std::string> expected_headers{
|
||||
"include/header.h", "include/subdir/header_link.h",
|
||||
"include/subdir_link/header_link.h", "libcxx/array"};
|
||||
ASSERT_EQ(headers, expected_headers);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user