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;
|
||||
}
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (firstNameEntry)
|
||||
name = projectName;
|
||||
name = targetName;
|
||||
|
||||
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;
|
||||
{
|
||||
const auto definitionFileName = projectName + ".zone";
|
||||
const auto definitionFileName = targetName + ".zone";
|
||||
const auto definitionStream = sourceSearchPath->Open(definitionFileName);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -213,14 +213,14 @@ class LinkerImpl final : public Linker
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!GetNameFromZoneDefinition(zoneDefinition->m_name, projectName, *zoneDefinition))
|
||||
if (!GetNameFromZoneDefinition(zoneDefinition->m_name, targetName, *zoneDefinition))
|
||||
return nullptr;
|
||||
|
||||
if (!IncludeAdditionalZoneDefinitions(projectName, *zoneDefinition, sourceSearchPath))
|
||||
if (!IncludeAdditionalZoneDefinitions(targetName, *zoneDefinition, sourceSearchPath))
|
||||
return nullptr;
|
||||
|
||||
if (!IncludeAssetLists(*zoneDefinition, sourceSearchPath))
|
||||
@ -229,7 +229,7 @@ class LinkerImpl final : public Linker
|
||||
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())
|
||||
return true;
|
||||
@ -242,7 +242,7 @@ class LinkerImpl final : public Linker
|
||||
|
||||
for (const auto& ignore : context.m_definition->m_ignores)
|
||||
{
|
||||
if (ignore == projectName)
|
||||
if (ignore == targetName)
|
||||
continue;
|
||||
|
||||
std::vector<AssetListEntry> assetList;
|
||||
@ -269,7 +269,7 @@ class LinkerImpl final : public Linker
|
||||
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;
|
||||
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_TYPE);
|
||||
@ -291,7 +291,7 @@ class LinkerImpl final : public Linker
|
||||
{
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
@ -304,7 +304,7 @@ class LinkerImpl final : public Linker
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -327,7 +327,7 @@ class LinkerImpl final : public Linker
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -360,13 +360,13 @@ class LinkerImpl final : public Linker
|
||||
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
|
||||
{
|
||||
const auto context = std::make_unique<ZoneCreationContext>(assetSearchPath, &zoneDefinition);
|
||||
if (!ProcessZoneDefinitionIgnores(projectName, *context, sourceSearchPath))
|
||||
if (!ProcessZoneDefinitionIgnores(targetName, *context, sourceSearchPath))
|
||||
return nullptr;
|
||||
if (!GetGameNameFromZoneDefinition(context->m_game_name, projectName, zoneDefinition))
|
||||
if (!GetGameNameFromZoneDefinition(context->m_game_name, targetName, zoneDefinition))
|
||||
return nullptr;
|
||||
if (!LoadGdtFilesFromZoneDefinition(context->m_gdt_files, zoneDefinition, gdtSearchPath))
|
||||
return nullptr;
|
||||
@ -405,9 +405,10 @@ class LinkerImpl final : public Linker
|
||||
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;
|
||||
if (zone)
|
||||
result = WriteZoneToFile(projectName, zone.get());
|
||||
@ -415,7 +416,7 @@ class LinkerImpl final : public Linker
|
||||
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));
|
||||
auto ipakFilePath(ipakFolderPath);
|
||||
@ -450,20 +451,20 @@ class LinkerImpl final : public Linker
|
||||
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);
|
||||
|
||||
const auto zoneDefinition = ReadZoneDefinition(projectName, &sourceSearchPaths);
|
||||
const auto zoneDefinition = ReadZoneDefinition(targetName, &sourceSearchPaths);
|
||||
if (!zoneDefinition)
|
||||
return false;
|
||||
|
||||
ProjectType projectType;
|
||||
if (!GetProjectTypeFromZoneDefinition(projectType, projectName, *zoneDefinition))
|
||||
if (!GetProjectTypeFromZoneDefinition(projectType, targetName, *zoneDefinition))
|
||||
return false;
|
||||
|
||||
std::string gameName;
|
||||
if (!GetGameNameFromZoneDefinition(gameName, projectName, *zoneDefinition))
|
||||
if (!GetGameNameFromZoneDefinition(gameName, targetName, *zoneDefinition))
|
||||
return false;
|
||||
utils::MakeStringLowerCase(gameName);
|
||||
|
||||
@ -474,11 +475,11 @@ class LinkerImpl final : public Linker
|
||||
switch (projectType)
|
||||
{
|
||||
case ProjectType::FASTFILE:
|
||||
result = BuildFastFile(projectName, *zoneDefinition, assetSearchPaths, gdtSearchPaths, sourceSearchPaths);
|
||||
result = BuildFastFile(projectName, targetName, *zoneDefinition, assetSearchPaths, gdtSearchPaths, sourceSearchPaths);
|
||||
break;
|
||||
|
||||
case ProjectType::IPAK:
|
||||
result = BuildIPak(projectName, *zoneDefinition, assetSearchPaths, sourceSearchPaths);
|
||||
result = BuildIPak(projectName, *zoneDefinition, assetSearchPaths);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -536,6 +537,40 @@ class LinkerImpl final : public Linker
|
||||
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:
|
||||
LinkerImpl()
|
||||
: m_search_paths(m_args)
|
||||
@ -554,9 +589,17 @@ public:
|
||||
return false;
|
||||
|
||||
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;
|
||||
break;
|
||||
|
@ -210,8 +210,8 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_projects_to_build = m_argument_parser.GetArguments();
|
||||
if (m_projects_to_build.empty())
|
||||
m_project_specifiers_to_build = m_argument_parser.GetArguments();
|
||||
if (m_project_specifiers_to_build.empty())
|
||||
{
|
||||
// No projects to build specified...
|
||||
PrintUsage();
|
||||
|
@ -41,7 +41,7 @@ private:
|
||||
|
||||
public:
|
||||
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_out_folder;
|
||||
|
Loading…
x
Reference in New Issue
Block a user