mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
Add possibility to build different targets in the same project for e.g. IPaks
This commit is contained in:
parent
2c09cc11e9
commit
0b4a0ac070
@ -168,7 +168,7 @@ class LinkerImpl final : public Linker
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GetNameFromZoneDefinition(std::string& name, const std::string& projectName, const ZoneDefinition& zoneDefinition)
|
static bool GetNameFromZoneDefinition(std::string& name, const std::string& targetName, const ZoneDefinition& zoneDefinition)
|
||||||
{
|
{
|
||||||
auto firstNameEntry = true;
|
auto firstNameEntry = true;
|
||||||
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_NAME);
|
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_NAME);
|
||||||
@ -183,27 +183,27 @@ class LinkerImpl final : public Linker
|
|||||||
{
|
{
|
||||||
if (name != i->second->m_value)
|
if (name != i->second->m_value)
|
||||||
{
|
{
|
||||||
std::cout << "Conflicting names in project \"" << projectName << "\": " << name << " != " << i->second << std::endl;
|
std::cout << "Conflicting names in target \"" << targetName << "\": " << name << " != " << i->second << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstNameEntry)
|
if (firstNameEntry)
|
||||||
name = projectName;
|
name = targetName;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ZoneDefinition> ReadZoneDefinition(const std::string& projectName, ISearchPath* sourceSearchPath) const
|
std::unique_ptr<ZoneDefinition> ReadZoneDefinition(const std::string& targetName, ISearchPath* sourceSearchPath) const
|
||||||
{
|
{
|
||||||
std::unique_ptr<ZoneDefinition> zoneDefinition;
|
std::unique_ptr<ZoneDefinition> zoneDefinition;
|
||||||
{
|
{
|
||||||
const auto definitionFileName = projectName + ".zone";
|
const auto definitionFileName = targetName + ".zone";
|
||||||
const auto definitionStream = sourceSearchPath->Open(definitionFileName);
|
const auto definitionStream = sourceSearchPath->Open(definitionFileName);
|
||||||
if (!definitionStream.IsOpen())
|
if (!definitionStream.IsOpen())
|
||||||
{
|
{
|
||||||
std::cout << "Could not find zone definition file for project \"" << projectName << "\"." << std::endl;
|
std::cout << "Could not find zone definition file for target \"" << targetName << "\"." << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,14 +213,14 @@ class LinkerImpl final : public Linker
|
|||||||
|
|
||||||
if (!zoneDefinition)
|
if (!zoneDefinition)
|
||||||
{
|
{
|
||||||
std::cout << "Failed to read zone definition file for project \"" << projectName << "\"." << std::endl;
|
std::cout << "Failed to read zone definition file for target \"" << targetName << "\"." << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetNameFromZoneDefinition(zoneDefinition->m_name, projectName, *zoneDefinition))
|
if (!GetNameFromZoneDefinition(zoneDefinition->m_name, targetName, *zoneDefinition))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!IncludeAdditionalZoneDefinitions(projectName, *zoneDefinition, sourceSearchPath))
|
if (!IncludeAdditionalZoneDefinitions(targetName, *zoneDefinition, sourceSearchPath))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!IncludeAssetLists(*zoneDefinition, sourceSearchPath))
|
if (!IncludeAssetLists(*zoneDefinition, sourceSearchPath))
|
||||||
@ -229,7 +229,7 @@ class LinkerImpl final : public Linker
|
|||||||
return zoneDefinition;
|
return zoneDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcessZoneDefinitionIgnores(const std::string& projectName, ZoneCreationContext& context, ISearchPath* sourceSearchPath) const
|
bool ProcessZoneDefinitionIgnores(const std::string& targetName, ZoneCreationContext& context, ISearchPath* sourceSearchPath) const
|
||||||
{
|
{
|
||||||
if (context.m_definition->m_ignores.empty())
|
if (context.m_definition->m_ignores.empty())
|
||||||
return true;
|
return true;
|
||||||
@ -242,7 +242,7 @@ class LinkerImpl final : public Linker
|
|||||||
|
|
||||||
for (const auto& ignore : context.m_definition->m_ignores)
|
for (const auto& ignore : context.m_definition->m_ignores)
|
||||||
{
|
{
|
||||||
if (ignore == projectName)
|
if (ignore == targetName)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::vector<AssetListEntry> assetList;
|
std::vector<AssetListEntry> assetList;
|
||||||
@ -269,7 +269,7 @@ class LinkerImpl final : public Linker
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GetProjectTypeFromZoneDefinition(ProjectType& projectType, const std::string& projectName, const ZoneDefinition& zoneDefinition)
|
static bool GetProjectTypeFromZoneDefinition(ProjectType& projectType, const std::string& targetName, const ZoneDefinition& zoneDefinition)
|
||||||
{
|
{
|
||||||
auto firstGameEntry = true;
|
auto firstGameEntry = true;
|
||||||
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_TYPE);
|
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_TYPE);
|
||||||
@ -291,7 +291,7 @@ class LinkerImpl final : public Linker
|
|||||||
{
|
{
|
||||||
if (projectType != parsedProjectType)
|
if (projectType != parsedProjectType)
|
||||||
{
|
{
|
||||||
std::cerr << "Conflicting types in project \"" << projectName << "\": " << PROJECT_TYPE_NAMES[static_cast<unsigned>(projectType)]
|
std::cerr << "Conflicting types in target \"" << targetName << "\": " << PROJECT_TYPE_NAMES[static_cast<unsigned>(projectType)]
|
||||||
<< " != " << PROJECT_TYPE_NAMES[static_cast<unsigned>(parsedProjectType)] << std::endl;
|
<< " != " << PROJECT_TYPE_NAMES[static_cast<unsigned>(parsedProjectType)] << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -304,7 +304,7 @@ class LinkerImpl final : public Linker
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GetGameNameFromZoneDefinition(std::string& gameName, const std::string& projectName, const ZoneDefinition& zoneDefinition)
|
static bool GetGameNameFromZoneDefinition(std::string& gameName, const std::string& targetName, const ZoneDefinition& zoneDefinition)
|
||||||
{
|
{
|
||||||
auto firstGameEntry = true;
|
auto firstGameEntry = true;
|
||||||
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_GAME);
|
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_GAME);
|
||||||
@ -319,7 +319,7 @@ class LinkerImpl final : public Linker
|
|||||||
{
|
{
|
||||||
if (gameName != i->second->m_value)
|
if (gameName != i->second->m_value)
|
||||||
{
|
{
|
||||||
std::cout << "Conflicting game names in project \"" << projectName << "\": " << gameName << " != " << i->second << std::endl;
|
std::cout << "Conflicting game names in target \"" << targetName << "\": " << gameName << " != " << i->second << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,7 +327,7 @@ class LinkerImpl final : public Linker
|
|||||||
|
|
||||||
if (firstGameEntry)
|
if (firstGameEntry)
|
||||||
{
|
{
|
||||||
std::cout << "No game name was specified for project \"" << projectName << "\"" << std::endl;
|
std::cout << "No game name was specified for target \"" << targetName << "\"" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,13 +360,13 @@ class LinkerImpl final : public Linker
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Zone> CreateZoneForDefinition(const std::string& projectName, ZoneDefinition& zoneDefinition, ISearchPath* assetSearchPath, ISearchPath* gdtSearchPath,
|
std::unique_ptr<Zone> CreateZoneForDefinition(const std::string& targetName, ZoneDefinition& zoneDefinition, ISearchPath* assetSearchPath, ISearchPath* gdtSearchPath,
|
||||||
ISearchPath* sourceSearchPath) const
|
ISearchPath* sourceSearchPath) const
|
||||||
{
|
{
|
||||||
const auto context = std::make_unique<ZoneCreationContext>(assetSearchPath, &zoneDefinition);
|
const auto context = std::make_unique<ZoneCreationContext>(assetSearchPath, &zoneDefinition);
|
||||||
if (!ProcessZoneDefinitionIgnores(projectName, *context, sourceSearchPath))
|
if (!ProcessZoneDefinitionIgnores(targetName, *context, sourceSearchPath))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!GetGameNameFromZoneDefinition(context->m_game_name, projectName, zoneDefinition))
|
if (!GetGameNameFromZoneDefinition(context->m_game_name, targetName, zoneDefinition))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!LoadGdtFilesFromZoneDefinition(context->m_gdt_files, zoneDefinition, gdtSearchPath))
|
if (!LoadGdtFilesFromZoneDefinition(context->m_gdt_files, zoneDefinition, gdtSearchPath))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -405,9 +405,10 @@ class LinkerImpl final : public Linker
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildFastFile(const std::string& projectName, ZoneDefinition& zoneDefinition, SearchPaths& assetSearchPaths, SearchPaths& gdtSearchPaths, SearchPaths& sourceSearchPaths) const
|
bool BuildFastFile(const std::string& projectName, const std::string& targetName, ZoneDefinition& zoneDefinition, SearchPaths& assetSearchPaths, SearchPaths& gdtSearchPaths,
|
||||||
|
SearchPaths& sourceSearchPaths) const
|
||||||
{
|
{
|
||||||
const auto zone = CreateZoneForDefinition(projectName, zoneDefinition, &assetSearchPaths, &gdtSearchPaths, &sourceSearchPaths);
|
const auto zone = CreateZoneForDefinition(targetName, zoneDefinition, &assetSearchPaths, &gdtSearchPaths, &sourceSearchPaths);
|
||||||
auto result = zone != nullptr;
|
auto result = zone != nullptr;
|
||||||
if (zone)
|
if (zone)
|
||||||
result = WriteZoneToFile(projectName, zone.get());
|
result = WriteZoneToFile(projectName, zone.get());
|
||||||
@ -415,7 +416,7 @@ class LinkerImpl final : public Linker
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildIPak(const std::string& projectName, const ZoneDefinition& zoneDefinition, SearchPaths& assetSearchPaths, SearchPaths& sourceSearchPaths) const
|
bool BuildIPak(const std::string& projectName, const ZoneDefinition& zoneDefinition, SearchPaths& assetSearchPaths) const
|
||||||
{
|
{
|
||||||
const fs::path ipakFolderPath(m_args.GetOutputFolderPathForProject(projectName));
|
const fs::path ipakFolderPath(m_args.GetOutputFolderPathForProject(projectName));
|
||||||
auto ipakFilePath(ipakFolderPath);
|
auto ipakFilePath(ipakFolderPath);
|
||||||
@ -450,20 +451,20 @@ class LinkerImpl final : public Linker
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildProject(const std::string& projectName)
|
bool BuildProject(const std::string& projectName, const std::string& targetName)
|
||||||
{
|
{
|
||||||
auto sourceSearchPaths = m_search_paths.GetSourceSearchPathsForProject(projectName);
|
auto sourceSearchPaths = m_search_paths.GetSourceSearchPathsForProject(projectName);
|
||||||
|
|
||||||
const auto zoneDefinition = ReadZoneDefinition(projectName, &sourceSearchPaths);
|
const auto zoneDefinition = ReadZoneDefinition(targetName, &sourceSearchPaths);
|
||||||
if (!zoneDefinition)
|
if (!zoneDefinition)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ProjectType projectType;
|
ProjectType projectType;
|
||||||
if (!GetProjectTypeFromZoneDefinition(projectType, projectName, *zoneDefinition))
|
if (!GetProjectTypeFromZoneDefinition(projectType, targetName, *zoneDefinition))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string gameName;
|
std::string gameName;
|
||||||
if (!GetGameNameFromZoneDefinition(gameName, projectName, *zoneDefinition))
|
if (!GetGameNameFromZoneDefinition(gameName, targetName, *zoneDefinition))
|
||||||
return false;
|
return false;
|
||||||
utils::MakeStringLowerCase(gameName);
|
utils::MakeStringLowerCase(gameName);
|
||||||
|
|
||||||
@ -474,11 +475,11 @@ class LinkerImpl final : public Linker
|
|||||||
switch (projectType)
|
switch (projectType)
|
||||||
{
|
{
|
||||||
case ProjectType::FASTFILE:
|
case ProjectType::FASTFILE:
|
||||||
result = BuildFastFile(projectName, *zoneDefinition, assetSearchPaths, gdtSearchPaths, sourceSearchPaths);
|
result = BuildFastFile(projectName, targetName, *zoneDefinition, assetSearchPaths, gdtSearchPaths, sourceSearchPaths);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProjectType::IPAK:
|
case ProjectType::IPAK:
|
||||||
result = BuildIPak(projectName, *zoneDefinition, assetSearchPaths, sourceSearchPaths);
|
result = BuildIPak(projectName, *zoneDefinition, assetSearchPaths);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -536,6 +537,40 @@ class LinkerImpl final : public Linker
|
|||||||
m_loaded_zones.clear();
|
m_loaded_zones.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool GetProjectAndTargetFromProjectSpecifier(const std::string& projectSpecifier, std::string& projectName, std::string& targetName)
|
||||||
|
{
|
||||||
|
const auto targetNameSeparatorIndex = projectSpecifier.find_first_of('/');
|
||||||
|
if (targetNameSeparatorIndex == std::string::npos)
|
||||||
|
{
|
||||||
|
projectName = projectSpecifier;
|
||||||
|
targetName = projectSpecifier;
|
||||||
|
}
|
||||||
|
else if (projectSpecifier.find_first_of('/', targetNameSeparatorIndex + 1) != std::string::npos)
|
||||||
|
{
|
||||||
|
std::cerr << "Project specifier cannot have more than one target name: \"" << projectSpecifier << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
projectName = projectSpecifier.substr(0, targetNameSeparatorIndex);
|
||||||
|
targetName = projectSpecifier.substr(targetNameSeparatorIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (projectName.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "Project name cannot be empty: \"" << projectSpecifier << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetName.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "Target name cannot be empty: \"" << projectSpecifier << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LinkerImpl()
|
LinkerImpl()
|
||||||
: m_search_paths(m_args)
|
: m_search_paths(m_args)
|
||||||
@ -554,9 +589,17 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto result = true;
|
auto result = true;
|
||||||
for (const auto& projectName : m_args.m_projects_to_build)
|
for (const auto& projectSpecifier : m_args.m_project_specifiers_to_build)
|
||||||
{
|
{
|
||||||
if (!BuildProject(projectName))
|
std::string projectName;
|
||||||
|
std::string targetName;
|
||||||
|
if (!GetProjectAndTargetFromProjectSpecifier(projectSpecifier, projectName, targetName))
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BuildProject(projectName, targetName))
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
|
@ -210,8 +210,8 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_projects_to_build = m_argument_parser.GetArguments();
|
m_project_specifiers_to_build = m_argument_parser.GetArguments();
|
||||||
if (m_projects_to_build.empty())
|
if (m_project_specifiers_to_build.empty())
|
||||||
{
|
{
|
||||||
// No projects to build specified...
|
// No projects to build specified...
|
||||||
PrintUsage();
|
PrintUsage();
|
||||||
|
@ -41,7 +41,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<std::string> m_zones_to_load;
|
std::vector<std::string> m_zones_to_load;
|
||||||
std::vector<std::string> m_projects_to_build;
|
std::vector<std::string> m_project_specifiers_to_build;
|
||||||
|
|
||||||
std::string m_base_folder;
|
std::string m_base_folder;
|
||||||
std::string m_out_folder;
|
std::string m_out_folder;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user