支持叠加编译

Signed-off-by: HanSY <hansiyuan1@huawei.com>
This commit is contained in:
HanSY
2024-11-12 11:39:23 +08:00
parent a8926b7797
commit f21607c496
21 changed files with 244 additions and 16 deletions
+4
View File
@@ -29,17 +29,21 @@ public:
~BinaryFilePacker();
std::future<uint32_t> CopyBinaryFileAsync(const std::vector<std::string> &inputs);
void StopCopy();
void SetCopyHapMode(bool state);
private:
uint32_t CopyBinaryFile(const std::vector<std::string> &inputs);
uint32_t CopyBinaryFile(const std::string &filePath, const std::string &fileType);
uint32_t CopyBinaryFileImpl(const std::string &src, const std::string &dst);
uint32_t CopySingleFile(const std::string &path, std::string &subPath);
uint32_t CopyBinaryFileWithHap(const std::vector<std::string> &inputs);
PackageParser packageParser_;
std::string moduleName_;
ThreadPool threadPool_;
std::vector<std::future<uint32_t>> copyResults_;
std::atomic<bool> stopCopy_{false};
bool copyHapMode_{false};
std::mutex mutex_;
};
} // namespace Restool
} // namespace Global
+3
View File
@@ -57,6 +57,8 @@ public:
bool IsTargetConfig() const;
const std::vector<std::string> &GetSysIdDefinedPaths() const;
const std::string &GetCompressionPath() const;
bool ExistIndex();
bool GetOverlap();
private:
void InitCommand();
@@ -112,6 +114,7 @@ private:
bool isTtargetConfig_;
std::vector<std::string> sysIdDefinedPaths_;
std::string compressionPath_;
bool overlap_ = false;
};
template<class T>
+3
View File
@@ -35,8 +35,10 @@ public:
{
moduleName_ = moduleName;
};
void SetHapItems();
uint32_t MergeResourceItem(const std::map<int64_t, std::vector<ResourceItem>> &resourceInfos);
bool ScaleIcons(const std::string &output, const std::map<std::string, std::set<uint32_t>> &iconMap);
void SetHapMode(bool state);
private:
uint32_t ScanModule(const std::string &input, const std::string &output);
@@ -47,6 +49,7 @@ private:
// id, resource items
std::map<int64_t, std::vector<ResourceItem>> items_;
std::string moduleName_;
bool hapMode_ = false;
};
}
}
+2
View File
@@ -33,6 +33,7 @@ public:
void SetModuleName(const std::string &moduleName);
uint32_t CompileForAppend(const FileInfo &fileInfo);
const std::map<std::pair<ResType, std::string>, std::vector<ResourceItem>> &GetResourceItems() const;
void SetHapRes();
protected:
virtual uint32_t CompileSingleFile(const FileInfo &fileInfo);
@@ -42,6 +43,7 @@ protected:
ResType type_;
std::string output_;
std::string moduleName_;
bool isHapRes_ = false;
// id, resource items
std::map<int64_t, std::vector<ResourceItem>> resourceInfos_;
+2
View File
@@ -19,6 +19,7 @@
#include <vector>
#include "id_defined_parser.h"
#include "resource_data.h"
#include "resource_item.h"
#include "resource_util.h"
#include "singleton.h"
@@ -32,6 +33,7 @@ public:
std::vector<ResourceId> GetHeaderId() const;
int64_t GetId(ResType resType, const std::string &name) const;
int64_t GetSystemId(ResType resType, const std::string &name) const;
void LoadIdFromHap(const std::map<int64_t, std::vector<ResourceItem>> &items);
private:
int64_t GenerateAppId(ResType resType, const std::string &name);
+1
View File
@@ -52,6 +52,7 @@ const static int32_t INT_TO_BYTES = sizeof(uint32_t);
static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 5.012" };
const static int32_t TAG_LEN = 4;
static std::set<std::string> g_resourceSet;
static std::set<std::string> g_hapResourceSet;
const static int8_t THREAD_POOL_SIZE = 2;
const static int8_t INVALID_ID = -1;
+4
View File
@@ -34,6 +34,7 @@ public:
void SetFilePath(const std::string &filePath);
void SetLimitKey(const std::string &limitKey);
void SetName(const std::string &name);
void SetHapRes();
const int8_t *GetData() const;
uint32_t GetDataLength() const;
@@ -43,6 +44,8 @@ public:
const std::string &GetFilePath() const;
const std::string &GetLimitKey() const;
bool IsHapRes() const;
ResourceItem &operator=(const ResourceItem &other);
private:
void ReleaseData();
@@ -54,6 +57,7 @@ private:
ResType type_;
std::string filePath_;
std::string limitKey_;
bool isHapRes_ = false;
};
}
}
+2 -1
View File
@@ -20,6 +20,7 @@
#include <vector>
#include "config_parser.h"
#include "restool_errors.h"
#include "cmd_parser.h"
namespace OHOS {
namespace Global {
@@ -28,7 +29,7 @@ class ResourceMerge {
public:
ResourceMerge();
virtual ~ResourceMerge();
uint32_t Init();
uint32_t Init(const PackageParser &packageParser = CmdParser<PackageParser>::GetInstance().GetCmdParser());
const std::vector<std::string> &GetInputs() const;
private:
std::vector<std::string> inputsOrder_;
+1 -1
View File
@@ -27,7 +27,7 @@ class ResourceModule {
public:
ResourceModule(const std::string &modulePath, const std::string &moduleOutput, const std::string &moduleName);
virtual ~ResourceModule() {};
uint32_t ScanResource();
uint32_t ScanResource(bool isHap = false);
const std::map<int64_t, std::vector<ResourceItem>> &GetOwner() const;
const std::map<ResType, std::vector<DirectoryInfo>> &GetScanDirectorys() const;
static uint32_t MergeResourceItem(std::map<int64_t, std::vector<ResourceItem>> &alls,
+2
View File
@@ -50,6 +50,7 @@ private:
uint32_t PackPreview();
uint32_t PackAppend();
uint32_t PackCombine();
uint32_t PackOverlap();
uint32_t PackQualifierResources(const ResourceMerge &resourceMerge);
uint32_t HandleFeature();
uint32_t FindResourceItems(const std::map<int64_t, std::vector<ResourceItem>> &resInfoLocal,
@@ -60,6 +61,7 @@ private:
void CheckConfigJson();
void CheckConfigJsonForCombine(ResourceAppend &resourceAppend);
bool CopyIcon(std::string &dataPath, const std::string &idName, std::string &fileName) const;
uint32_t LoadHapResources();
PackageParser packageParser_;
std::string moduleName_;
using HeaderCreater = std::function<uint32_t(const std::string&)>;
+41 -2
View File
@@ -39,13 +39,38 @@ void BinaryFilePacker::StopCopy()
stopCopy_.store(true);
}
void BinaryFilePacker::SetCopyHapMode(bool state)
{
copyHapMode_ = state;
}
std::future<uint32_t> BinaryFilePacker::CopyBinaryFileAsync(const std::vector<std::string> &inputs)
{
auto func = [this](const std::vector<std::string> &inputs) { return this->CopyBinaryFile(inputs); };
if (copyHapMode_) {
auto func = [this](const vector<string> &inputs) { return this->CopyBinaryFileWithHap(inputs); };
future<uint32_t> res = threadPool_.Enqueue(func, inputs);
return res;
}
auto func = [this](const vector<string> &inputs) { return this->CopyBinaryFile(inputs); };
std::future<uint32_t> res = threadPool_.Enqueue(func, inputs);
return res;
}
uint32_t BinaryFilePacker::CopyBinaryFileWithHap(const vector<string> &inputs)
{
vector<string> hapResource(inputs.begin(), inputs.begin() + 1);
if (CopyBinaryFile(hapResource) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
copyResults_.clear();
SetCopyHapMode(false);
vector<string> resource(inputs.begin() + 1, inputs.end());
if (CopyBinaryFile(resource) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
return RESTOOL_SUCCESS;
}
uint32_t BinaryFilePacker::CopyBinaryFile(const vector<string> &inputs)
{
for (const auto &input : inputs) {
@@ -116,14 +141,28 @@ uint32_t BinaryFilePacker::CopyBinaryFileImpl(const string &src, const string &d
continue;
}
if (!g_resourceSet.emplace(subPath).second) {
bool hapEmplaceSuccess = true;
bool gResEmplaceSuccess = true;
lock_guard<mutex> lock(mutex_);
if (copyHapMode_) {
hapEmplaceSuccess = g_hapResourceSet.emplace(subPath).second;
gResEmplaceSuccess = g_resourceSet.emplace(subPath).second;
} else if (g_hapResourceSet.count(subPath)) { // overlap the hap resource by new resource
g_hapResourceSet.erase(subPath);
} else {
gResEmplaceSuccess = g_resourceSet.emplace(subPath).second;
}
if (!hapEmplaceSuccess || !gResEmplaceSuccess) {
cerr << "Warning: '" << entry->GetFilePath().GetPath() << "' is defined repeatedly." << endl;
continue;
}
if (stopCopy_.load()) {
cout << "Info: CopyBinaryFileImpl: stop copy binary file." << endl;
return RESTOOL_ERROR;
}
string path = entry->GetFilePath().GetPath();
auto copyFunc = [this](const string path, string subPath) { return this->CopySingleFile(path, subPath); };
std::future<uint32_t> res = threadPool_.Enqueue(copyFunc, path, subPath);
+20
View File
@@ -18,6 +18,7 @@
#include "resconfig_parser.h"
#include "resource_util.h"
#include "select_compile_parse.h"
#include "file_entry.h"
namespace OHOS {
namespace Global {
@@ -443,6 +444,25 @@ const std::string &PackageParser::GetCompressionPath() const
return compressionPath_;
}
bool PackageParser::ExistIndex()
{
for (auto &input : inputs_) {
string indexPath = ResourceUtil::GetMainPath(input).Append(RESOURCE_INDEX_FILE).GetPath();
if (ResourceUtil::FileExist(indexPath)) {
inputs_.erase(find(inputs_.begin(), inputs_.end(), input));
inputs_.emplace(inputs_.begin(), input);
overlap_ = true;
return true;
}
}
return false;
}
bool PackageParser::GetOverlap()
{
return overlap_;
}
void PackageParser::InitCommand()
{
using namespace placeholders;
+19 -2
View File
@@ -42,7 +42,19 @@ uint32_t FileManager::ScanModules(const vector<string> &inputs, const string &ou
if (!noBaseResource.empty()) {
ResourceUtil::PrintWarningMsg(noBaseResource);
}
return isHar ? RESTOOL_SUCCESS : ParseReference(output);
if (hapMode_) {
SetHapItems();
}
return isHar || hapMode_ ? RESTOOL_SUCCESS : ParseReference(output);
}
void FileManager::SetHapItems()
{
for (auto &item : items_) {
for (auto &resourceItem : item.second) {
resourceItem.SetHapRes();
}
}
}
uint32_t FileManager::MergeResourceItem(const map<int64_t, vector<ResourceItem>> &resourceInfos)
@@ -54,7 +66,7 @@ uint32_t FileManager::MergeResourceItem(const map<int64_t, vector<ResourceItem>>
uint32_t FileManager::ScanModule(const string &input, const string &output)
{
ResourceModule resourceModule(input, output, moduleName_);
if (resourceModule.ScanResource() != RESTOOL_SUCCESS) {
if (resourceModule.ScanResource(hapMode_) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
MergeResourceItem(resourceModule.GetOwner());
@@ -120,6 +132,11 @@ bool FileManager::ScaleIcons(const string &output, const std::map<std::string, s
return true;
}
void FileManager::SetHapMode(bool state)
{
hapMode_ = state;
}
bool FileManager::ScaleIcon(const string &output, ResourceItem &item)
{
std::string media = "media";
+12 -1
View File
@@ -101,7 +101,18 @@ bool GenericCompiler::IsIgnore(const FileInfo &fileInfo)
{
std::lock_guard<std::mutex> lock(mutex_);
string output = GetOutputFilePath(fileInfo);
if (!g_resourceSet.emplace(output).second) {
bool hapEmplaceSuccess = true;
bool gResEmplaceSuccess = true;
if (isHapRes_) {
hapEmplaceSuccess = g_hapResourceSet.emplace(output).second;
gResEmplaceSuccess = g_resourceSet.emplace(output).second;
} else if (g_hapResourceSet.count(output)) { // overlap the hap resource by new resource
g_hapResourceSet.erase(output);
} else {
gResEmplaceSuccess = g_resourceSet.emplace(output).second;
}
if (!hapEmplaceSuccess || !gResEmplaceSuccess) {
cerr << "Warning: '" << fileInfo.filePath << "' is defined repeatedly." << endl;
return true;
}
+5
View File
@@ -104,6 +104,11 @@ const map<pair<ResType, string>, vector<ResourceItem>> &IResourceCompiler::GetRe
return nameInfos_;
}
void IResourceCompiler::SetHapRes()
{
isHapRes_ = true;
}
void IResourceCompiler::SetModuleName(const string &moduleName)
{
moduleName_ = moduleName;
+15
View File
@@ -84,6 +84,21 @@ int64_t IdWorker::GetSystemId(ResType resType, const string &name) const
return result->second.id;
}
void IdWorker::LoadIdFromHap(const map<int64_t, vector<ResourceItem>> &items)
{
int64_t minId = 0xffffffff;
int64_t maxId = 0x01000000;
for (const auto &item : items) {
for (const auto &resourceItem : item.second) {
ids_.emplace(make_pair(resourceItem.GetResType(), resourceItem.GetName()), item.first);
}
minId = min(minId, item.first);
maxId = max(maxId, item.first);
}
maxId_ = GetMaxId(minId);
appId_ = maxId + 1;
}
int64_t IdWorker::GenerateAppId(ResType resType, const string &name)
{
auto result = ids_.find(make_pair(resType, name));
+11
View File
@@ -85,6 +85,11 @@ void ResourceItem::SetName(const string &name)
name_ = name;
}
void ResourceItem::SetHapRes()
{
isHapRes_ = true;
}
const int8_t *ResourceItem::GetData() const
{
return data_;
@@ -120,6 +125,11 @@ const string &ResourceItem::GetLimitKey() const
return limitKey_;
}
bool ResourceItem::IsHapRes() const
{
return isHapRes_;
}
ResourceItem &ResourceItem::operator=(const ResourceItem &other)
{
if (this == &other) {
@@ -147,6 +157,7 @@ void ResourceItem::CopyFrom(const ResourceItem &other)
dataLen_ = other.dataLen_;
filePath_ = other.filePath_;
limitKey_ = other.limitKey_;
isHapRes_ = other.isHapRes_;
if (!SetData(other.data_, other.dataLen_)) {
ReleaseData();
}
+13 -6
View File
@@ -14,7 +14,6 @@
*/
#include "resource_merge.h"
#include "cmd_parser.h"
#include "file_entry.h"
namespace OHOS {
@@ -37,21 +36,26 @@ ResourceMerge::~ResourceMerge()
{
}
uint32_t ResourceMerge::Init()
uint32_t ResourceMerge::Init(const PackageParser &packageParser)
{
auto &cmdParser = CmdParser<PackageParser>::GetInstance().GetCmdParser();
const vector<string> &inputs = cmdParser.GetInputs();
if (cmdParser.IsFileList()) {
const vector<string> &inputs = packageParser.GetInputs();
if (packageParser.IsFileList()) {
inputsOrder_ = inputs;
return RESTOOL_SUCCESS;
}
map<ConfigParser::ModuleType, vector<string>> inputTypes;
string hapDir = "";
for (auto it = inputs.crbegin(); it != inputs.crend(); it++) {
string configPath = ResourceUtil::GetMainPath(*it).Append(ConfigParser::GetConfigName()).GetPath();
string resourceDir = FileEntry::FilePath(*it).GetPath();
string indexPath = ResourceUtil::GetMainPath(*it).Append(RESOURCE_INDEX_FILE).GetPath();
if (ResourceUtil::FileExist(indexPath)) {
hapDir = resourceDir;
continue;
}
ConfigParser::ModuleType moduleType = ConfigParser::ModuleType::NONE;
if (!ResourceUtil::FileExist(configPath)) {
if (!ResourceUtil::FileExist(configPath) || ResourceUtil::FileExist(indexPath)) {
inputTypes[moduleType].push_back(resourceDir);
continue;
}
@@ -69,6 +73,9 @@ uint32_t ResourceMerge::Init()
}
inputsOrder_.insert(inputsOrder_.end(), inputTypes[type].begin(), inputTypes[type].end());
}
if (hapDir != "") {
inputsOrder_.insert(inputsOrder_.begin(), hapDir);
}
return RESTOOL_SUCCESS;
}
+8 -1
View File
@@ -33,7 +33,7 @@ ResourceModule::ResourceModule(const string &modulePath, const string &moduleOut
{
}
uint32_t ResourceModule::ScanResource()
uint32_t ResourceModule::ScanResource(bool isHap)
{
if (!ResourceUtil::FileExist(modulePath_)) {
return RESTOOL_SUCCESS;
@@ -56,6 +56,9 @@ uint32_t ResourceModule::ScanResource()
unique_ptr<IResourceCompiler> resourceCompiler =
FactoryResourceCompiler::CreateCompiler(type, moduleOutput_);
resourceCompiler->SetModuleName(moduleName_);
if (isHap) {
resourceCompiler->SetHapRes();
}
if (resourceCompiler->Compile(item->second) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
@@ -91,6 +94,10 @@ uint32_t ResourceModule::MergeResourceItem(map<int64_t, vector<ResourceItem>> &a
result.first->second.push_back(resourceItem);
continue;
}
if (ret->IsHapRes()) { // overlap the hap resource by new resource
*ret = resourceItem;
continue;
}
if (tipError) {
cerr << "Error: '"<< resourceItem.GetName() <<"' conflict, first declared.";
cerr << NEW_LINE_PATH << ret->GetFilePath() << endl;
+72 -2
View File
@@ -42,6 +42,10 @@ uint32_t ResourcePack::Package()
if (packageParser_.GetCombine()) {
return PackCombine();
}
if (packageParser_.ExistIndex()) {
return PackOverlap();
}
return PackNormal();
}
@@ -272,8 +276,20 @@ uint32_t ResourcePack::ScanResources(const vector<string> &inputs, const string
{
auto &fileManager = FileManager::GetInstance();
fileManager.SetModuleName(moduleName_);
if (fileManager.ScanModules(inputs, output, configJson_.IsHar()) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
if (packageParser_.GetOverlap()) {
vector<string> hapResInput{inputs[0]};
if (fileManager.ScanModules(hapResInput, output, configJson_.IsHar()) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
fileManager.SetHapMode(false);
vector<string> resInputs(inputs.begin() + 1, inputs.end());
if (fileManager.ScanModules(resInputs, output, configJson_.IsHar()) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
} else {
if (fileManager.ScanModules(inputs, output, configJson_.IsHar()) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
}
return RESTOOL_SUCCESS;
}
@@ -555,6 +571,60 @@ uint32_t ResourcePack::PackCombine()
return RESTOOL_SUCCESS;
}
uint32_t ResourcePack::PackOverlap()
{
if (InitCompression() != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
if (Init() != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
ResourceMerge resourceMerge;
if (resourceMerge.Init(packageParser_) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
BinaryFilePacker rawFilePacker(packageParser_, moduleName_);
rawFilePacker.SetCopyHapMode(true);
std::future<uint32_t> copyFuture = rawFilePacker.CopyBinaryFileAsync(resourceMerge.GetInputs());
if (LoadHapResources() != RESTOOL_SUCCESS) {
rawFilePacker.StopCopy();
return RESTOOL_ERROR;
}
if (PackQualifierResources(resourceMerge) != RESTOOL_SUCCESS) {
rawFilePacker.StopCopy();
return RESTOOL_ERROR;
}
uint32_t copyRet = copyFuture.get();
return copyRet == RESTOOL_SUCCESS ? RESTOOL_SUCCESS : RESTOOL_ERROR;
}
uint32_t ResourcePack::LoadHapResources()
{
ResourceTable resourceTabel;
map<int64_t, vector<ResourceItem>> items;
string resourceIndexPath =
FileEntry::FilePath(packageParser_.GetInputs()[0]).GetParent().Append(RESOURCE_INDEX_FILE).GetPath();
if (resourceTabel.LoadResTable(resourceIndexPath, items) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
IdWorker::GetInstance().LoadIdFromHap(items);
FileManager &fileManager = FileManager::GetInstance();
fileManager.SetModuleName(moduleName_);
if (fileManager.MergeResourceItem(items) != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
fileManager.SetHapItems();
fileManager.SetHapMode(true);
return RESTOOL_SUCCESS;
}
void ResourcePack::CheckConfigJsonForCombine(ResourceAppend &resourceAppend)
{
ResourceCheck resourceCheck(configJson_.GetCheckNode(), make_shared<ResourceAppend>(resourceAppend));
+4
View File
@@ -489,9 +489,13 @@ bool ResourceTable::ReadDataRecordStart(std::ifstream &in, RecordItem &record,
cerr << "Error: invalid resources.index limit key offset." << endl;
return false;
}
const vector<KeyParam> &keyparams = limitKeys.find(datas.find(offset)->second.second)->second;
ResourceItem resourceitem(filename, keyparams, g_resTypeMap.find(record.resType)->second);
resourceitem.SetLimitKey(ResourceUtil::PaserKeyParam(keyparams));
if (values[value_size - 1] == '\0') {
value_size--;
}
resourceitem.SetData(values, value_size);
resInfos[record.id].push_back(resourceitem);
return true;