/* * Copyright (C) 2016 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 "make.h" #include "command.h" #include "print.h" #include "util.h" #include #include #include #include #include #include #include #include #include #include using namespace std; static bool map_contains(const map& m, const string& k, const string& v) { map::const_iterator it = m.find(k); if (it == m.end()) { return false; } return it->second == v; } static string make_cache_filename(const string& outDir) { string filename(outDir); return filename + "/.bit_cache"; } bool Module::HasClass(const string& cl) { for (vector::const_iterator c = classes.begin(); c != classes.end(); c++) { if (*c == cl) { return true; } } return false; } BuildVars::BuildVars(const string& outDir, const string& buildProduct, const string& buildVariant, const string& buildType) :m_filename(), m_cache() { m_cache["TARGET_PRODUCT"] = buildProduct; m_cache["TARGET_BUILD_VARIANT"] = buildVariant; m_cache["TARGET_BUILD_TYPE"] = buildType; // If we have any problems reading the file, that's ok, just do // uncached calls to make / soong. if (outDir == "") { return; } m_filename = make_cache_filename(outDir); std::ifstream stream(m_filename, std::ifstream::binary); if (stream.fail()) { return; } Json::Value json; Json::CharReaderBuilder builder; if (!Json::parseFromStream(builder, stream, &json, /* errorMessage = */ nullptr)) { return; } if (!json.isObject()) { return; } map cache; vector names = json.getMemberNames(); const int N = names.size(); for (int i=0; i const writer(factory.newStreamWriter()); Json::Value json(Json::objectValue); for (map::const_iterator it = m_cache.begin(); it != m_cache.end(); it++) { json[it->first] = it->second; } std::ofstream stream(m_filename, std::ofstream::binary); writer->write(json, &stream); } string BuildVars::GetBuildVar(const string& name, bool quiet) { int err; map::iterator it = m_cache.find(name); if (it == m_cache.end()) { Command cmd("build/soong/soong_ui.bash"); cmd.AddArg("--dumpvar-mode"); cmd.AddArg(name); string output = trim(get_command_output(cmd, &err, quiet)); if (err == 0) { m_cache[name] = output; save(); return output; } else { return string(); } } else { return it->second; } } void json_error(const string& filename, const char* error, bool quiet) { if (!quiet) { print_error("Unable to parse module info file (%s): %s", error, filename.c_str()); print_error("Have you done a full build?"); } exit(1); } static void get_values(const Json::Value& json, const string& name, vector* result) { Json::Value nullValue; const Json::Value& value = json.get(name, nullValue); if (!value.isArray()) { return; } const int N = value.size(); for (int i=0; ipush_back(child.asString()); } } } void read_modules(const string& buildOut, const string& device, map* result, bool quiet) { string filename(string(buildOut + "/target/product/") + device + "/module-info.json"); std::ifstream stream(filename, std::ifstream::binary); if (stream.fail()) { if (!quiet) { print_error("Unable to open module info file: %s", filename.c_str()); print_error("Have you done a full build?"); } exit(1); } Json::Value json; Json::CharReaderBuilder builder; if (!Json::parseFromStream(builder, stream, &json, /* errorMessage = */ nullptr)) { json_error(filename, "can't parse json format", quiet); return; } if (!json.isObject()) { json_error(filename, "root element not an object", quiet); return; } vector names = json.getMemberNames(); const int N = names.size(); for (int i=0; i= 0; i--) { string cl = module.classes[i]; if (!(cl == "JAVA_LIBRARIES" || cl == "EXECUTABLES" || cl == "SHARED_LIBRARIES" || cl == "APPS" || cl == "NATIVE_TESTS")) { module.classes.erase(module.classes.begin() + i); } } if (module.classes.size() == 0) { continue; } // Only target modules (not host) for (ssize_t i = module.installed.size() - 1; i >= 0; i--) { string fn = module.installed[i]; if (!starts_with(fn, buildOut + "/target/")) { module.installed.erase(module.installed.begin() + i); } } if (module.installed.size() == 0) { continue; } (*result)[name] = module; } } int build_goals(const vector& goals) { Command cmd("build/soong/soong_ui.bash"); cmd.AddArg("--make-mode"); for (size_t i=0; i