From: Jooyung Han Date: Thu, 20 Feb 2020 09:21:03 +0000 (+0900) Subject: Trim root path from output X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=471aeb93d9a67ce2cc8efbac94d4e0203b7d2bd6;p=android-x86%2Fsystem-linkerconfig.git Trim root path from output When linkerconfig runs on host with --root argument, it prints root as well like following: $ linkerconfig --vndk R --root /tmp/test_root ... namespace.foo.search_paths = /tmp/test_root/product/${LIB} .. This change trims root from path variables and apex paths so the output look more like real output. Bug: n/a Test: build/boot run linkerconfig on host and compare outputs Change-Id: Icc91f297047f059684a42d825048e50e26873520 --- diff --git a/contents/configuration/baseconfig.cc b/contents/configuration/baseconfig.cc index 41b2731..d9aa86d 100644 --- a/contents/configuration/baseconfig.cc +++ b/contents/configuration/baseconfig.cc @@ -58,12 +58,12 @@ android::linkerconfig::modules::Configuration CreateBaseConfiguration( std::vector dirToSection = { {"/system/bin/", "system"}, {"/system/xbin/", "system"}, - {"/" + Var("SYSTEM_EXT", "system_ext") + "/bin/", "system"}, + {Var("SYSTEM_EXT") + "/bin/", "system"}, // Processes from the product partition will have a separate section if // PRODUCT_PRODUCT_VNDK_VERSION is defined. Otherwise, they are run from // the "system" section. - {"/" + Var("PRODUCT", "product") + "/bin/", "product"}, + {Var("PRODUCT") + "/bin/", "product"}, {"/odm/bin/", "vendor"}, {"/vendor/bin/", "vendor"}, diff --git a/contents/configuration/legacy.cc b/contents/configuration/legacy.cc index 52e0186..b857a3d 100644 --- a/contents/configuration/legacy.cc +++ b/contents/configuration/legacy.cc @@ -35,8 +35,8 @@ android::linkerconfig::modules::Configuration CreateLegacyConfiguration( const std::vector kDirToSection = { // All binaries gets the same configuration 'legacy' {"/system", "legacy"}, - {"/" + Var("SYSTEM_EXT", "system_ext"), "legacy"}, - {"/" + Var("PRODUCT", "product"), "legacy"}, + {Var("SYSTEM_EXT"), "legacy"}, + {Var("PRODUCT"), "legacy"}, {"/vendor", "legacy"}, {"/odm", "legacy"}, {"/sbin", "legacy"}, diff --git a/contents/namespace/postinstall.cc b/contents/namespace/postinstall.cc index 89e75e4..4eed9ea 100644 --- a/contents/namespace/postinstall.cc +++ b/contents/namespace/postinstall.cc @@ -26,9 +26,8 @@ Namespace BuildPostInstallNamespace([[maybe_unused]] const Context& ctx) { Namespace ns("default", /*is_isolated=*/false, /*is_visible=*/false); ns.AddSearchPath("/system/${LIB}", AsanPath::NONE); - ns.AddSearchPath("/" + Var("SYSTEM_EXT", "system_ext") + "/${LIB}", - AsanPath::NONE); - ns.AddSearchPath("/" + Var("PRODUCT", "product") + "/${LIB}", AsanPath::NONE); + ns.AddSearchPath(Var("SYSTEM_EXT") + "/${LIB}", AsanPath::NONE); + ns.AddSearchPath(Var("PRODUCT") + "/${LIB}", AsanPath::NONE); return ns; } diff --git a/contents/namespace/productdefault.cc b/contents/namespace/productdefault.cc index 98eca47..23fe083 100644 --- a/contents/namespace/productdefault.cc +++ b/contents/namespace/productdefault.cc @@ -29,9 +29,9 @@ namespace contents { Namespace BuildProductDefaultNamespace([[maybe_unused]] const Context& ctx) { Namespace ns("default", /*is_isolated=*/true, /*is_visible=*/true); - ns.AddSearchPath("/" + Var("PRODUCT", "product") + "/${LIB}", + ns.AddSearchPath(Var("PRODUCT", "product") + "/${LIB}", AsanPath::WITH_DATA_ASAN); - ns.AddPermittedPath("/" + Var("PRODUCT", "product"), AsanPath::WITH_DATA_ASAN); + ns.AddPermittedPath(Var("PRODUCT", "product"), AsanPath::WITH_DATA_ASAN); ns.GetLink(ctx.GetSystemNamespaceName()) .AddSharedLib(Var("LLNDK_LIBRARIES_PRODUCT")); diff --git a/contents/namespace/system.cc b/contents/namespace/system.cc index 1c8c1a1..97de965 100644 --- a/contents/namespace/system.cc +++ b/contents/namespace/system.cc @@ -31,11 +31,9 @@ namespace contents { Namespace BuildSystemNamespace([[maybe_unused]] const Context& ctx) { Namespace ns("system", /*is_isolated=*/false, /*is_visible=*/false); ns.AddSearchPath("/system/${LIB}", AsanPath::WITH_DATA_ASAN); - ns.AddSearchPath("/" + Var("SYSTEM_EXT", "system_ext") + "/${LIB}", - AsanPath::WITH_DATA_ASAN); + ns.AddSearchPath(Var("SYSTEM_EXT") + "/${LIB}", AsanPath::WITH_DATA_ASAN); if (!IsProductVndkVersionDefined()) { - ns.AddSearchPath("/" + Var("PRODUCT", "product") + "/${LIB}", - AsanPath::WITH_DATA_ASAN); + ns.AddSearchPath(Var("PRODUCT") + "/${LIB}", AsanPath::WITH_DATA_ASAN); } ns.AddRequires(std::vector{"libdexfile_external.so", diff --git a/contents/namespace/systemdefault.cc b/contents/namespace/systemdefault.cc index 98296ab..37a5ea3 100644 --- a/contents/namespace/systemdefault.cc +++ b/contents/namespace/systemdefault.cc @@ -31,8 +31,8 @@ namespace linkerconfig { namespace contents { Namespace BuildSystemDefaultNamespace([[maybe_unused]] const Context& ctx) { bool is_fully_treblelized = ctx.IsDefaultConfig(); - std::string product = Var("PRODUCT", "product"); - std::string system_ext = Var("SYSTEM_EXT", "system_ext"); + std::string product = Var("PRODUCT"); + std::string system_ext = Var("SYSTEM_EXT"); // Visible to allow links to be created at runtime, e.g. through // android_link_namespaces in libnativeloader. @@ -41,11 +41,11 @@ Namespace BuildSystemDefaultNamespace([[maybe_unused]] const Context& ctx) { /*is_visible=*/true); ns.AddSearchPath("/system/${LIB}", AsanPath::WITH_DATA_ASAN); - ns.AddSearchPath("/" + system_ext + "/${LIB}", AsanPath::WITH_DATA_ASAN); + ns.AddSearchPath(system_ext + "/${LIB}", AsanPath::WITH_DATA_ASAN); if (!IsProductVndkVersionDefined() || !is_fully_treblelized) { // System processes can search product libs only if product VNDK is not // enforced. - ns.AddSearchPath("/" + product + "/${LIB}", AsanPath::WITH_DATA_ASAN); + ns.AddSearchPath(product + "/${LIB}", AsanPath::WITH_DATA_ASAN); } if (!is_fully_treblelized) { ns.AddSearchPath("/vendor/${LIB}", AsanPath::WITH_DATA_ASAN); @@ -64,7 +64,7 @@ Namespace BuildSystemDefaultNamespace([[maybe_unused]] const Context& ctx) { "/system/${LIB}/drm", "/system/${LIB}/extractors", "/system/${LIB}/hw", - "/" + system_ext + "/${LIB}", + system_ext + "/${LIB}", // These are where odex files are located. libart has to be able to // dlopen the files @@ -72,9 +72,9 @@ Namespace BuildSystemDefaultNamespace([[maybe_unused]] const Context& ctx) { "/system/app", "/system/priv-app", - "/" + system_ext + "/framework", - "/" + system_ext + "/app", - "/" + system_ext + "/priv-app", + system_ext + "/framework", + system_ext + "/app", + system_ext + "/priv-app", "/vendor/framework", "/vendor/app", "/vendor/priv-app", @@ -85,9 +85,9 @@ Namespace BuildSystemDefaultNamespace([[maybe_unused]] const Context& ctx) { "/odm/app", "/odm/priv-app", "/oem/app", - "/" + product + "/framework", - "/" + product + "/app", - "/" + product + "/priv-app", + product + "/framework", + product + "/app", + product + "/priv-app", "/data", "/mnt/expand", "/apex/com.android.runtime/${LIB}/bionic", @@ -98,7 +98,7 @@ Namespace BuildSystemDefaultNamespace([[maybe_unused]] const Context& ctx) { } if (!IsProductVndkVersionDefined()) { // System processes can use product libs only if product VNDK is not enforced. - ns.AddPermittedPath("/" + product + "/${LIB}", AsanPath::SAME_PATH); + ns.AddPermittedPath(product + "/${LIB}", AsanPath::SAME_PATH); } } diff --git a/contents/namespace/vendordefault.cc b/contents/namespace/vendordefault.cc index 3539ab4..51e7160 100644 --- a/contents/namespace/vendordefault.cc +++ b/contents/namespace/vendordefault.cc @@ -67,10 +67,8 @@ Namespace BuildVendorDefaultNamespace([[maybe_unused]] const Context& ctx) { // VNDK-Lite devices require broader access from vendor to system/product partition if (is_vndklite) { ns.AddSearchPath("/system/${LIB}", AsanPath::WITH_DATA_ASAN); - ns.AddSearchPath("/" + Var("SYSTEM_EXT", "system_ext") + "/${LIB}", - AsanPath::WITH_DATA_ASAN); - ns.AddSearchPath("/" + Var("PRODUCT", "product") + "/${LIB}", - AsanPath::WITH_DATA_ASAN); + ns.AddSearchPath(Var("SYSTEM_EXT") + "/${LIB}", AsanPath::WITH_DATA_ASAN); + ns.AddSearchPath(Var("PRODUCT") + "/${LIB}", AsanPath::WITH_DATA_ASAN); // Put system vndk at the last search order in vndk_lite for GSI ns.AddSearchPath( "/apex/com.android.vndk.v" + Var("VENDOR_VNDK_VERSION") + "/${LIB}", diff --git a/contents/namespace/vndkinsystem.cc b/contents/namespace/vndkinsystem.cc index 071e08c..77d243a 100644 --- a/contents/namespace/vndkinsystem.cc +++ b/contents/namespace/vndkinsystem.cc @@ -42,11 +42,9 @@ Namespace BuildVndkInSystemNamespace([[maybe_unused]] const Context& ctx) { // The search paths here should be kept the same as that of the 'system' namespace. ns.AddSearchPath("/system/${LIB}", AsanPath::WITH_DATA_ASAN); - ns.AddSearchPath("/" + Var("SYSTEM_EXT", "system_ext") + "/${LIB}", - AsanPath::WITH_DATA_ASAN); + ns.AddSearchPath(Var("SYSTEM_EXT") + "/${LIB}", AsanPath::WITH_DATA_ASAN); if (!IsProductVndkVersionDefined()) { - ns.AddSearchPath("/" + Var("PRODUCT", "product") + "/${LIB}", - AsanPath::WITH_DATA_ASAN); + ns.AddSearchPath(Var("PRODUCT") + "/${LIB}", AsanPath::WITH_DATA_ASAN); } if (android::linkerconfig::modules::IsVndkInSystemNamespace()) { diff --git a/contents/tests/backward_compatibility/testbase.h b/contents/tests/backward_compatibility/testbase.h index 83d9aa2..193b85e 100644 --- a/contents/tests/backward_compatibility/testbase.h +++ b/contents/tests/backward_compatibility/testbase.h @@ -38,6 +38,9 @@ inline void MockVariables(std::string vndk_ver = "Q") { MockVndkVariables("PRODUCT", vndk_ver); Variables::AddValue("ro.product.vndk.version", vndk_ver); + Variables::AddValue("SYSTEM_EXT", "/system_ext"); + Variables::AddValue("PRODUCT", "/procut"); + Variables::AddValue("VNDK_USING_CORE_VARIANT_LIBRARIES", "vndk_using_core_variant_libraries"); Variables::AddValue("STUB_LIBRARIES", "stub_libraries"); diff --git a/generator/variableloader.cc b/generator/variableloader.cc index 8a60de0..4cd0e83 100644 --- a/generator/variableloader.cc +++ b/generator/variableloader.cc @@ -25,11 +25,13 @@ #include "linkerconfig/environment.h" #include "linkerconfig/librarylistloader.h" #include "linkerconfig/log.h" +#include "linkerconfig/stringutil.h" #include "linkerconfig/variables.h" using android::base::Result; using android::linkerconfig::modules::GetProductVndkVersion; using android::linkerconfig::modules::GetVendorVndkVersion; +using android::linkerconfig::modules::TrimPrefix; using android::linkerconfig::modules::Variables; namespace { @@ -78,30 +80,29 @@ void LoadVndkVersionVariable() { Result GetRealPath(std::string target_path) { char resolved_path[PATH_MAX]; if (realpath(target_path.c_str(), resolved_path) != nullptr) { - int start_index = 0; - if (resolved_path[0] == '/') { - start_index = 1; - } - return &resolved_path[start_index]; + return resolved_path; } return ErrnoErrorf("Failed to get realpath from {}", target_path); } -void LoadVariableFromPartitionPath(std::string variable_name, std::string path) { - auto real_path = GetRealPath(path); +void LoadVariableFromPartitionPath(const std::string& root, + std::string variable_name, + std::string partition) { + auto real_path = GetRealPath(root + partition); if (real_path.ok()) { - Variables::AddValue(variable_name, *real_path); + Variables::AddValue(variable_name, TrimPrefix(*real_path, root)); } else { LOG(WARNING) << real_path.error(); + Variables::AddValue(variable_name, partition); } } void LoadPartitionPathVariables(const std::string& root) { // TODO(b/141714913): generalize path handling - LoadVariableFromPartitionPath("PRODUCT", root + "/product"); - LoadVariableFromPartitionPath("SYSTEM_EXT", root + "/system_ext"); + LoadVariableFromPartitionPath(root, "PRODUCT", "/product"); + LoadVariableFromPartitionPath(root, "SYSTEM_EXT", "/system_ext"); } void LoadVndkLibraryListVariables(const std::string& root, diff --git a/main.cc b/main.cc index d82ebf6..de7ba23 100644 --- a/main.cc +++ b/main.cc @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include +#include #include #include #include @@ -23,9 +23,12 @@ #include #include +#include #include #include +#include + #include "linkerconfig/apex.h" #include "linkerconfig/apexconfig.h" #include "linkerconfig/baseconfig.h" @@ -81,6 +84,14 @@ struct ProgramArgs { exit(status); } +std::string RealPath(std::string_view path) { + char resolved_path[PATH_MAX]; + if (realpath(path.data(), resolved_path) != nullptr) { + return resolved_path; + } + PrintUsage(-1); +} + bool ParseArgs(int argc, char* argv[], ProgramArgs* args) { int parse_result; while ((parse_result = getopt_long( @@ -93,7 +104,7 @@ bool ParseArgs(int argc, char* argv[], ProgramArgs* args) { args->strict = true; break; case 'r': - args->root = optarg; + args->root = RealPath(optarg); break; case 'v': args->vndk_version = optarg; @@ -170,8 +181,7 @@ Result UpdatePermission([[maybe_unused]] const std::string& file_path) { } Context GetContext(ProgramArgs args) { - const std::string apex_root = args.root + "/apex"; - auto apex_list = android::linkerconfig::modules::ScanActiveApexes(apex_root); + auto apex_list = android::linkerconfig::modules::ScanActiveApexes(args.root); Context ctx; for (auto const& apex_item : apex_list) { auto apex_info = apex_item.second; diff --git a/modules/apex.cc b/modules/apex.cc index 6c71073..9c31979 100644 --- a/modules/apex.cc +++ b/modules/apex.cc @@ -19,22 +19,28 @@ #include +#include "linkerconfig/stringutil.h" + namespace { + bool DirExists(const std::string& path) { return access(path.c_str(), F_OK) == 0; } + } // namespace namespace android { namespace linkerconfig { namespace modules { -std::map ScanActiveApexes(const std::string& apex_root) { + +std::map ScanActiveApexes(const std::string& root) { std::map apexes; + const auto apex_root = root + apex::kApexRoot; for (const auto& [path, manifest] : apex::GetActivePackages(apex_root)) { bool has_bin = DirExists(path + "/bin"); bool has_lib = DirExists(path + "/lib") || DirExists(path + "/lib64"); ApexInfo info(manifest.name(), - path, + TrimPrefix(path, root), {manifest.providenativelibs().begin(), manifest.providenativelibs().end()}, {manifest.requirenativelibs().begin(), @@ -45,6 +51,7 @@ std::map ScanActiveApexes(const std::string& apex_root) { } return apexes; } + } // namespace modules } // namespace linkerconfig } // namespace android \ No newline at end of file diff --git a/modules/include/linkerconfig/apex.h b/modules/include/linkerconfig/apex.h index 4e0a6dc..8fb7d32 100644 --- a/modules/include/linkerconfig/apex.h +++ b/modules/include/linkerconfig/apex.h @@ -48,7 +48,7 @@ struct ApexInfo { } }; -std::map ScanActiveApexes(const std::string& apex_root); +std::map ScanActiveApexes(const std::string& root); } // namespace modules } // namespace linkerconfig } // namespace android \ No newline at end of file diff --git a/modules/include/linkerconfig/stringutil.h b/modules/include/linkerconfig/stringutil.h new file mode 100644 index 0000000..f5896f5 --- /dev/null +++ b/modules/include/linkerconfig/stringutil.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include + +namespace android { +namespace linkerconfig { +namespace modules { +std::string TrimPrefix(const std::string& s, const std::string& prefix); +} +} // namespace linkerconfig +} // namespace android \ No newline at end of file diff --git a/modules/stringutil.cc b/modules/stringutil.cc new file mode 100644 index 0000000..e695e3b --- /dev/null +++ b/modules/stringutil.cc @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "linkerconfig/stringutil.h" + +#include + +namespace android { +namespace linkerconfig { +namespace modules { +std::string TrimPrefix(const std::string& s, const std::string& prefix) { + if (android::base::StartsWith(s, prefix)) { + return s.substr(prefix.size()); + } + return s; +} +} // namespace modules +} // namespace linkerconfig +} // namespace android \ No newline at end of file diff --git a/modules/tests/apex_test.cc b/modules/tests/apex_test.cc index b3b2053..2385d0f 100644 --- a/modules/tests/apex_test.cc +++ b/modules/tests/apex_test.cc @@ -96,11 +96,11 @@ TEST(apex_namespace, resolve_between_apex_namespaces) { TEST_F(ApexTest, scan_apex_dir) { PrepareApex("foo", {}, {"bar.so"}); - WriteFile("foo/bin/foo", ""); + WriteFile("/apex/foo/bin/foo", ""); PrepareApex("bar", {"bar.so"}, {}); - WriteFile("bar/lib64/bar.so", ""); + WriteFile("/apex/bar/lib64/bar.so", ""); - auto apexes = ScanActiveApexes(apex_root); + auto apexes = ScanActiveApexes(root); ASSERT_EQ(2U, apexes.size()); ASSERT_THAT(apexes["foo"].require_libs, Contains("bar.so")); diff --git a/modules/tests/apex_testbase.h b/modules/tests/apex_testbase.h index a7f5e87..d32086e 100644 --- a/modules/tests/apex_testbase.h +++ b/modules/tests/apex_testbase.h @@ -21,12 +21,14 @@ #include "linkerconfig/apex.h" +#include + struct ApexTest : ::testing::Test { TemporaryDir tmp_dir; - std::string apex_root; + std::string root; void SetUp() override { - apex_root = tmp_dir.path + std::string("/"); + root = tmp_dir.path; } android::linkerconfig::modules::ApexInfo PrepareApex( @@ -40,10 +42,11 @@ struct ApexTest : ::testing::Test { for (auto lib : required_libs) { manifest.add_requirenativelibs(lib); } - WriteFile(apex_name + "/apex_manifest.pb", manifest.SerializeAsString()); + const auto apex_path = "/apex/" + apex_name; + WriteFile(apex_path + "/apex_manifest.pb", manifest.SerializeAsString()); return android::linkerconfig::modules::ApexInfo( manifest.name(), - tmp_dir.path, + apex_path, {manifest.providenativelibs().begin(), manifest.providenativelibs().end()}, {manifest.requirenativelibs().begin(), @@ -55,13 +58,15 @@ struct ApexTest : ::testing::Test { void Mkdir(std::string dir_path) { if (access(dir_path.c_str(), F_OK) == 0) return; Mkdir(android::base::Dirname(dir_path)); + std::cout << "mkdir(" + dir_path + ")\n"; ASSERT_NE(-1, mkdir(dir_path.c_str(), 0755) == -1) << "Failed to create a directory: " << dir_path; } void WriteFile(std::string file, std::string content) { - std::string file_path = apex_root + file; + std::string file_path = root + file; Mkdir(::android::base::Dirname(file_path)); + std::cout << "writeFile(" + file_path + ")\n"; ASSERT_TRUE(::android::base::WriteStringToFile(content, file_path)) << "Failed to write a file: " << file_path; }