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{
|
static const std::vector<std::string> header_extensions{
|
||||||
".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"};
|
".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(),
|
return std::find_if(header_extensions.begin(), header_extensions.end(),
|
||||||
[file_name](const std::string &e) {
|
[file_name](const std::string &e) {
|
||||||
return file_name.endswith(e);
|
return file_name.endswith(e);
|
||||||
}) != header_extensions.end();
|
}) != 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() {
|
static std::string GetCwd() {
|
||||||
llvm::SmallString<256> cwd;
|
llvm::SmallString<256> cwd;
|
||||||
if (llvm::sys::fs::current_path(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,
|
static bool CollectExportedHeaderSet(const std::string &dir_name,
|
||||||
std::set<std::string> *exported_headers,
|
std::set<std::string> *exported_headers,
|
||||||
const RootDirs &root_dirs) {
|
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;
|
std::error_code ec;
|
||||||
llvm::sys::fs::recursive_directory_iterator walker(dir_name, ec);
|
llvm::sys::fs::recursive_directory_iterator walker(dir_name, ec);
|
||||||
// Default construction - end of directory.
|
// Default construction - end of directory.
|
||||||
@@ -136,7 +160,11 @@ static bool CollectExportedHeaderSet(const std::string &dir_name,
|
|||||||
walker.no_push();
|
walker.no_push();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!HasHeaderExtension(file_name)) {
|
if (!file_name.contains(".")) {
|
||||||
|
if (!collect_headers_without_extensions) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (!HasHeaderExtension(file_name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,14 +24,20 @@ namespace header_checker {
|
|||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
TEST(SourcePathUtilsTest, CollectAllExportedHeaders) {
|
TEST(SourcePathUtilsTest, CollectAllExportedHeaders) {
|
||||||
// Prepare a header directory.
|
|
||||||
TemporaryDir temp_dir;
|
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";
|
const std::filesystem::path header = header_dir / "header.h";
|
||||||
ASSERT_TRUE(android::base::WriteStringToFile("// test", header));
|
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";
|
const std::filesystem::path subdir = header_dir / "subdir";
|
||||||
ASSERT_TRUE(std::filesystem::create_directory(subdir, ec));
|
ASSERT_TRUE(std::filesystem::create_directory(subdir, ec));
|
||||||
ASSERT_FALSE(ec);
|
ASSERT_FALSE(ec);
|
||||||
@@ -55,15 +61,24 @@ TEST(SourcePathUtilsTest, CollectAllExportedHeaders) {
|
|||||||
const std::filesystem::path non_header_link = subdir / "header_link.txt";
|
const std::filesystem::path non_header_link = subdir / "header_link.txt";
|
||||||
std::filesystem::create_symlink(header, non_header_link, ec);
|
std::filesystem::create_symlink(header, non_header_link, ec);
|
||||||
ASSERT_FALSE(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.
|
// Test the function.
|
||||||
std::vector<std::string> exported_header_dirs{header_dir};
|
std::vector<std::string> exported_header_dirs{header_dir, libcxx_dir};
|
||||||
std::vector<RootDir> root_dirs{{header_dir, "include"}};
|
std::vector<RootDir> root_dirs{{header_dir, "include"},
|
||||||
|
{libcxx_dir, "libcxx"}};
|
||||||
std::set<std::string> headers =
|
std::set<std::string> headers =
|
||||||
CollectAllExportedHeaders(exported_header_dirs, root_dirs);
|
CollectAllExportedHeaders(exported_header_dirs, root_dirs);
|
||||||
|
|
||||||
std::set<std::string> expected_headers{"include/header.h",
|
std::set<std::string> expected_headers{
|
||||||
"include/subdir/header_link.h",
|
"include/header.h", "include/subdir/header_link.h",
|
||||||
"include/subdir_link/header_link.h"};
|
"include/subdir_link/header_link.h", "libcxx/array"};
|
||||||
ASSERT_EQ(headers, expected_headers);
|
ASSERT_EQ(headers, expected_headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user