/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "config.h"
#include "codeblocks.h"
#include
#include
namespace CreateProjectTool {
CodeBlocksProvider::CodeBlocksProvider(StringList &global_warnings, std::map &project_warnings, StringList &global_errors)
: ProjectProvider(global_warnings, project_warnings, global_errors) {
}
void CodeBlocksProvider::createWorkspace(const BuildSetup &setup) {
std::ofstream workspace((setup.outputDir + '/' + setup.projectName + ".workspace").c_str());
if (!workspace)
error("Could not open \"" + setup.outputDir + '/' + setup.projectName + ".workspace\" for writing");
workspace << "\n"
"\n";
workspace << "\t\n";
writeReferences(setup, workspace);
// Note we assume that the UUID map only includes UUIDs for enabled engines!
for (const auto &i : _engineUuidMap) {
workspace << "\t\t\n";
}
workspace << "\t\n"
"";
}
StringList getFeatureLibraries(const BuildSetup &setup) {
StringList libraries;
std::string libSDL = "lib";
libSDL += setup.getSDLName();
libraries.push_back(libSDL);
for (const auto &feature : setup.features) {
if (feature.enable && feature.library) {
std::string libname;
if (!std::strcmp(feature.name, "libcurl")) {
libname = feature.name;
} else if (!std::strcmp(feature.name, "zlib")) {
libname = "libz";
} else if (!std::strcmp(feature.name, "vorbis")) {
libname = "libvorbis";
libraries.push_back("libvorbisfile");
} else if (!std::strcmp(feature.name, "png")) {
libname = "libpng16";
} else if (!std::strcmp(feature.name, "sdlnet")) {
libname = libSDL + "_net";
libraries.push_back("iphlpapi");
} else {
libname = "lib";
libname += feature.name;
}
libraries.push_back(libname);
}
}
// Win32 libraries
libraries.push_back("ole32");
libraries.push_back("uuid");
libraries.push_back("winmm");
return libraries;
}
void CodeBlocksProvider::createProjectFile(const std::string &name, const std::string &, const BuildSetup &setup, const std::string &moduleDir,
const StringList &includeList, const StringList &excludeList, const std::string &pchIncludeRoot, const StringList &pchDirs, const StringList &pchExclude) {
const std::string projectFile = setup.outputDir + '/' + name + getProjectExtension();
std::ofstream project(projectFile.c_str());
if (!project)
error("Could not open \"" + projectFile + "\" for writing");
project << "\n"
"\n"
"\t\n"
"\t\n"
"\t\t\n"
"\t\t\n"
"\t\t\n"
"\t\t\n";
if (name == setup.projectName) {
StringList libraries = getFeatureLibraries(setup);
std::string deps;
for (const auto &library : libraries)
deps += library + ".a;";
project << "\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n";
//////////////////////////////////////////////////////////////////////////
// Compiler
project << "\t\t\t\t\n";
writeWarnings(name, project);
writeDefines(setup.defines, project);
for (const auto &includeDir : setup.includeDirs)
project << "\t\t\t\t\t\n";
project << "\t\t\t\t\t\n"
"\t\t\t\t\t\n"
"\t\t\t\t\t\n"
"\t\t\t\t\t\n"
"\t\t\t\t\t\n"
"\t\t\t\t\t\n"
"\t\t\t\t\n";
//////////////////////////////////////////////////////////////////////////
// Linker
project << "\t\t\t\t\n";
for (const auto &library : libraries)
project << "\t\t\t\t\t\n";
for (const auto &i : _engineUuidMap) {
project << "\t\t\t\t\t\n";
}
for (const auto &libraryDir : setup.libraryDirs)
project << "\t\t\t\t\t\n";
project << "\t\t\t\t\t\n"
"\t\t\t\t\t\n"
"\t\t\t\t\n";
//////////////////////////////////////////////////////////////////////////
// Resource compiler
project << "\t\t\t\t\n"
"\t\t\t\t\t\n"
"\t\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\n"
"\t\t\n";
} else {
project << "\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n"
"\t\t\t\t\n";
writeWarnings(name, project);
writeDefines(setup.defines, project);
project << "\t\t\t\t\t\n"
"\t\t\t\t\t\n"
"\t\t\t\t\t\n";
// Sword2.5 engine needs theora and vorbis includes
if (name == "sword25")
project << "\t\t\t\t\t\n";
project << "\t\t\t\t\n"
"\t\t\t\n"
"\t\t\n";
}
std::string modulePath;
if (!moduleDir.compare(0, setup.srcDir.size(), setup.srcDir)) {
modulePath = moduleDir.substr(setup.srcDir.size());
if (!modulePath.empty() && modulePath.at(0) == '/')
modulePath.erase(0, 1);
}
if (!modulePath.empty())
addFilesToProject(moduleDir, project, includeList, excludeList, pchIncludeRoot, pchDirs, pchExclude, setup.filePrefix + '/' + modulePath);
else
addFilesToProject(moduleDir, project, includeList, excludeList, pchIncludeRoot, pchDirs, pchExclude, setup.filePrefix);
project << "\t\t\n"
"\t\t\t\n"
"\t\t\t\n"
"\t\t\n"
"\t\n"
"";
}
void CodeBlocksProvider::addResourceFiles(const BuildSetup &setup, StringList &includeList, StringList &excludeList) {
includeList.push_back(setup.srcDir + "/icons/" + setup.projectName + ".ico");
includeList.push_back(setup.srcDir + "/dists/" + setup.projectName + ".rc");
}
void CodeBlocksProvider::writeWarnings(const std::string &name, std::ofstream &output) const {
// Global warnings
for (const auto &_globalWarning : _globalWarnings)
output << "\t\t\t\t\t\n";
// Check for project-specific warnings:
std::map::iterator warningsIterator = _projectWarnings.find(name);
if (warningsIterator != _projectWarnings.end())
for (const auto &i : warningsIterator->second)
output << "\t\t\t\t\t\n";
}
void CodeBlocksProvider::writeDefines(const StringList &defines, std::ofstream &output) const {
for (const auto &define : defines)
output << "\t\t\t\t\t\n";
}
void CodeBlocksProvider::writeFileListToProject(const FileNode &dir, std::ostream &projectFile, const int indentation,
const std::string &objPrefix, const std::string &filePrefix,
const std::string &pchIncludeRoot, const StringList &pchDirs, const StringList &pchExclude) {
for (const auto *node : dir.children) {
if (!node->children.empty()) {
writeFileListToProject(*node, projectFile, indentation + 1, objPrefix + node->name + '_', filePrefix + node->name + '/', pchIncludeRoot, pchDirs, pchExclude);
} else {
std::string name, ext;
splitFilename(node->name, name, ext);
if (ext == "rc") {
projectFile << "\t\tname) << "\">\n"
"\t\t\t\n"
"\t\t\n";
} else if (ext == "asm") {
projectFile << "\t\tname) << "\">\n"
"\t\t\t"
"\t\t\n";
} else {
projectFile << "\t\tname) << "\" />\n";
}
}
}
}
void CodeBlocksProvider::writeReferences(const BuildSetup &setup, std::ofstream &output) {
output << "\t\t\n";
for (const auto &i : _engineUuidMap) {
output << "\t\t\t\n";
}
output << "\t\t\n";
}
const char *CodeBlocksProvider::getProjectExtension() {
return ".cbp";
}
} // End of CreateProjectTool namespace