diff options
Diffstat (limited to 'tools/versioner/src/versioner.cpp')
-rw-r--r-- | tools/versioner/src/versioner.cpp | 74 |
1 files changed, 50 insertions, 24 deletions
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp index 735ea04e9..bb09bea9e 100644 --- a/tools/versioner/src/versioner.cpp +++ b/tools/versioner/src/versioner.cpp @@ -44,6 +44,7 @@ #include <android-base/file.h> #include <android-base/macros.h> #include <android-base/parseint.h> +#include <android-base/strings.h> #include "Arch.h" #include "DeclarationDatabase.h" @@ -78,11 +79,21 @@ static int getCpuCount() { #endif } -static CompilationRequirements collectRequirements(const Arch& arch, const std::string& header_dir, - const std::string& dependency_dir) { - std::vector<std::string> headers = collectHeaders(header_dir); - std::vector<std::string> dependencies = { header_dir }; - if (!dependency_dir.empty()) { +namespace { +struct HeaderLocationInformation { + std::string header_dir; + std::string dependency_dir; + // Absolute paths to ignore all children -- including subdirectories -- of. + std::unordered_set<std::string> ignored_directories; +}; +} + +static CompilationRequirements collectRequirements(const Arch& arch, + const HeaderLocationInformation& location) { + std::vector<std::string> headers = + collectHeaders(location.header_dir, location.ignored_directories); + std::vector<std::string> dependencies = { location.header_dir }; + if (!location.dependency_dir.empty()) { auto collect_children = [&dependencies](const std::string& dir_path) { DIR* dir = opendir(dir_path.c_str()); if (!dir) { @@ -113,8 +124,8 @@ static CompilationRequirements collectRequirements(const Arch& arch, const std:: closedir(dir); }; - collect_children(dependency_dir + "/common"); - collect_children(dependency_dir + "/" + to_string(arch)); + collect_children(location.dependency_dir + "/common"); + collect_children(location.dependency_dir + "/" + to_string(arch)); } auto new_end = std::remove_if(headers.begin(), headers.end(), [&arch](llvm::StringRef header) { @@ -158,13 +169,12 @@ static std::set<CompilationType> generateCompilationTypes(const std::set<Arch> s } static std::unique_ptr<HeaderDatabase> compileHeaders(const std::set<CompilationType>& types, - const std::string& header_dir, - const std::string& dependency_dir) { + const HeaderLocationInformation& location) { if (types.empty()) { errx(1, "compileHeaders received no CompilationTypes"); } - auto vfs = createCommonVFS(header_dir, dependency_dir, add_include); + auto vfs = createCommonVFS(location.header_dir, location.dependency_dir, add_include); size_t thread_count = max_thread_count; std::vector<std::thread> threads; @@ -175,7 +185,7 @@ static std::unique_ptr<HeaderDatabase> compileHeaders(const std::set<Compilation auto result = std::make_unique<HeaderDatabase>(); for (const auto& type : types) { if (requirements.count(type.arch) == 0) { - requirements[type.arch] = collectRequirements(type.arch, header_dir, dependency_dir); + requirements[type.arch] = collectRequirements(type.arch, location); } } @@ -438,6 +448,7 @@ static void usage(bool help = false) { fprintf(stderr, " -f\t\tpreprocess header files even if validation fails\n"); fprintf(stderr, "\n"); fprintf(stderr, "Miscellaneous:\n"); + fprintf(stderr, " -F\t\tdo not ignore FORTIFY headers by default\n"); fprintf(stderr, " -d\t\tdump function availability\n"); fprintf(stderr, " -j THREADS\tmaximum number of threads to use\n"); fprintf(stderr, " -v\t\tenable verbose logging\n"); @@ -461,9 +472,10 @@ int main(int argc, char** argv) { std::string preprocessor_output_path; bool force = false; bool dump = false; + bool ignore_fortify_headers = true; int c; - while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhi")) != -1) { + while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhFi")) != -1) { default_args = false; switch (c) { case 'a': { @@ -549,6 +561,10 @@ int main(int argc, char** argv) { add_include = true; break; + case 'F': + ignore_fortify_headers = false; + break; + default: usage(); break; @@ -559,8 +575,7 @@ int main(int argc, char** argv) { usage(); } - std::string header_dir; - std::string dependency_dir; + HeaderLocationInformation location; const char* top = getenv("ANDROID_BUILD_TOP"); if (!top && (optind == argc || add_include)) { @@ -571,19 +586,30 @@ int main(int argc, char** argv) { if (optind == argc) { // Neither HEADER_PATH nor DEPS_PATH were specified, so try to figure them out. std::string versioner_dir = to_string(top) + "/bionic/tools/versioner"; - header_dir = versioner_dir + "/current"; - dependency_dir = versioner_dir + "/dependencies"; + location.header_dir = versioner_dir + "/current"; + location.dependency_dir = versioner_dir + "/dependencies"; if (platform_dir.empty()) { platform_dir = versioner_dir + "/platforms"; } } else { - if (!android::base::Realpath(argv[optind], &header_dir)) { + if (!android::base::Realpath(argv[optind], &location.header_dir)) { err(1, "failed to get realpath for path '%s'", argv[optind]); } if (argc - optind == 2) { - dependency_dir = argv[optind + 1]; + location.dependency_dir = argv[optind + 1]; + } + } + + // Every file that lives in bits/fortify is logically a part of a header outside of bits/fortify. + // This makes the files there impossible to build on their own. + if (ignore_fortify_headers) { + std::string fortify_path = location.header_dir; + if (!android::base::EndsWith(location.header_dir, "/")) { + fortify_path += '/'; } + fortify_path += "bits/fortify"; + location.ignored_directories.insert(std::move(fortify_path)); } if (selected_levels.empty()) { @@ -596,10 +622,10 @@ int main(int argc, char** argv) { struct stat st; - if (stat(header_dir.c_str(), &st) != 0) { - err(1, "failed to stat '%s'", header_dir.c_str()); + if (const char *dir = location.header_dir.c_str(); stat(dir, &st) != 0) { + err(1, "failed to stat '%s'", dir); } else if (!S_ISDIR(st.st_mode)) { - errx(1, "'%s' is not a directory", header_dir.c_str()); + errx(1, "'%s' is not a directory", dir); } std::set<CompilationType> compilation_types; @@ -615,7 +641,7 @@ int main(int argc, char** argv) { auto start = std::chrono::high_resolution_clock::now(); std::unique_ptr<HeaderDatabase> declaration_database = - compileHeaders(compilation_types, header_dir, dependency_dir); + compileHeaders(compilation_types, location); auto end = std::chrono::high_resolution_clock::now(); if (verbose) { @@ -625,7 +651,7 @@ int main(int argc, char** argv) { bool failed = false; if (dump) { - declaration_database->dump(header_dir + "/"); + declaration_database->dump(location.header_dir + "/"); } else { if (!sanityCheck(declaration_database.get())) { printf("versioner: sanity check failed\n"); @@ -641,7 +667,7 @@ int main(int argc, char** argv) { } if (!preprocessor_output_path.empty() && (force || !failed)) { - failed = !preprocessHeaders(preprocessor_output_path, header_dir, declaration_database.get()); + failed = !preprocessHeaders(preprocessor_output_path, location.header_dir, declaration_database.get()); } return failed; } |