DEVTOOLS: Adapt create_project for new configure.engine files.

I could not try any generated project files since I do not have access to
the IDEs.
This commit is contained in:
Johannes Schickel 2013-11-07 12:58:34 +01:00 committed by D G Turner
parent ef85456859
commit 6e29e1abee
2 changed files with 152 additions and 58 deletions

View file

@ -81,22 +81,6 @@ std::string unifyPath(const std::string &path);
* @param exe Name of the executable. * @param exe Name of the executable.
*/ */
void displayHelp(const char *exe); void displayHelp(const char *exe);
/**
* Structure for describing an FSNode. This is a very minimalistic
* description, which includes everything we need.
* It only contains the name of the node and whether it is a directory
* or not.
*/
struct FSNode {
FSNode() : name(), isDirectory(false) {}
FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {}
std::string name; ///< Name of the file system node
bool isDirectory; ///< Whether it is a directory or not
};
typedef std::list<FSNode> FileList;
} // End of anonymous namespace } // End of anonymous namespace
enum ProjectType { enum ProjectType {
@ -128,7 +112,7 @@ int main(int argc, char *argv[]) {
setup.filePrefix = setup.srcDir; setup.filePrefix = setup.srcDir;
setup.outputDir = '.'; setup.outputDir = '.';
setup.engines = parseConfigure(setup.srcDir); setup.engines = parseEngines(setup.srcDir);
if (setup.engines.empty()) { if (setup.engines.empty()) {
std::cout << "WARNING: No engines found in configure file or configure file missing in \"" << setup.srcDir << "\"\n"; std::cout << "WARNING: No engines found in configure file or configure file missing in \"" << setup.srcDir << "\"\n";
@ -672,47 +656,51 @@ void displayHelp(const char *exe) {
} }
/** /**
* Try to parse a given line and create an engine definition * Parse the configure.engine file of a given engine directory and return a
* out of the result. * list of all defined engines.
* *
* This may take *any* input line, when the line is not used * @param engineDir The directory of the engine.
* to define an engine the result of the function will be "false". * @return The list of all defined engines.
*
* Note that the contents of "engine" are undefined, when this
* function returns "false".
*
* @param line Text input line.
* @param engine Reference to an object, where the engine information
* is to be stored in.
* @return "true", when parsing succeeded, "false" otherwise.
*/ */
bool parseEngine(const std::string &line, EngineDesc &engine); EngineDescList parseEngineConfigure(const std::string &engineDir);
/**
* Compares two FSNode entries in a strict-weak fashion based on the name.
*
* @param left The first operand.
* @param right The second operand.
* @return "true" when the name of the left operand is strictly smaller than
* the name of the second operand. "false" otherwise.
*/
bool compareFSNode(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right);
} // End of anonymous namespace } // End of anonymous namespace
EngineDescList parseConfigure(const std::string &srcDir) { EngineDescList parseEngines(const std::string &srcDir) {
std::string configureFile = srcDir + "/engines/configure.engines"; using CreateProjectTool::FileList;
using CreateProjectTool::listDirectory;
std::ifstream configure(configureFile.c_str()); EngineDescList engineList;
if (!configure)
return EngineDescList();
std::string line; FileList engineFiles = listDirectory(srcDir + "/engines/");
EngineDescList engines;
for (;;) { // Sort file list alphabetically this allows for a nicer order in
std::getline(configure, line); // --list-engines output, for example.
if (configure.eof()) engineFiles.sort(&compareFSNode);
break;
if (configure.fail()) for (FileList::const_iterator i = engineFiles.begin(), end = engineFiles.end(); i != end; ++i) {
error("Failed while reading from " + configureFile); // Each engine requires its own sub directory thus we will skip all
// non directory file nodes here.
if (!i->isDirectory) {
continue;
}
EngineDesc desc; // Retrieve all engines defined in this sub directory and add them to
if (parseEngine(line, desc)) // the list of all engines.
engines.push_back(desc); EngineDescList list = parseEngineConfigure(srcDir + "/engines/" + i->name);
engineList.splice(engineList.end(), list);
} }
return engines; return engineList;
} }
bool isSubEngine(const std::string &name, const EngineDescList &engines) { bool isSubEngine(const std::string &name, const EngineDescList &engines) {
@ -777,6 +765,21 @@ StringList getEngineDefines(const EngineDescList &engines) {
} }
namespace { namespace {
/**
* Try to parse a given line and create an engine definition
* out of the result.
*
* This may take *any* input line, when the line is not used
* to define an engine the result of the function will be "false".
*
* Note that the contents of "engine" are undefined, when this
* function returns "false".
*
* @param line Text input line.
* @param engine Reference to an object, where the engine information
* is to be stored in.
* @return "true", when parsing succeeded, "false" otherwise.
*/
bool parseEngine(const std::string &line, EngineDesc &engine) { bool parseEngine(const std::string &line, EngineDesc &engine) {
// Format: // Format:
// add_engine engine_name "Readable Description" enable_default ["SubEngineList"] // add_engine engine_name "Readable Description" enable_default ["SubEngineList"]
@ -799,6 +802,36 @@ bool parseEngine(const std::string &line, EngineDesc &engine) {
return true; return true;
} }
EngineDescList parseEngineConfigure(const std::string &engineDir) {
std::string configureFile = engineDir + "/configure.engine";
std::ifstream configure(configureFile.c_str());
if (!configure)
return EngineDescList();
std::string line;
EngineDescList engines;
for (;;) {
std::getline(configure, line);
if (configure.eof())
break;
if (configure.fail())
error("Failed while reading from " + configureFile);
EngineDesc desc;
if (parseEngine(line, desc))
engines.push_back(desc);
}
return engines;
}
bool compareFSNode(const CreateProjectTool::FSNode &left, const CreateProjectTool::FSNode &right) {
return left.name < right.name;
}
} // End of anonymous namespace } // End of anonymous namespace
TokenList tokenize(const std::string &input, char separator) { TokenList tokenize(const std::string &input, char separator) {
@ -1048,13 +1081,6 @@ bool compareNodes(const FileNode *l, const FileNode *r) {
} }
} }
/**
* Returns a list of all files and directories in the specified
* path.
*
* @param dir Directory which should be listed.
* @return List of all children.
*/
FileList listDirectory(const std::string &dir) { FileList listDirectory(const std::string &dir) {
FileList result; FileList result;
#ifdef USE_WIN32_API #ifdef USE_WIN32_API
@ -1242,6 +1268,12 @@ void ProjectProvider::createProject(BuildSetup &setup) {
// Create other misc. build files // Create other misc. build files
createOtherBuildFiles(setup); createOtherBuildFiles(setup);
// In case we create the main ScummVM project files we will need to
// generate engines/plugins_table.h too.
if (!setup.tests && !setup.devTools) {
createEnginePluginsTable(setup);
}
} }
ProjectProvider::UUIDMap ProjectProvider::createUUIDMap(const BuildSetup &setup) const { ProjectProvider::UUIDMap ProjectProvider::createUUIDMap(const BuildSetup &setup) const {
@ -1569,6 +1601,33 @@ void ProjectProvider::createModuleList(const std::string &moduleDir, const Strin
error("Malformed file " + moduleMkFile); error("Malformed file " + moduleMkFile);
} }
void ProjectProvider::createEnginePluginsTable(const BuildSetup &setup) {
const std::string enginePluginsTableFile = setup.outputDir + "/engines/plugins_table.h";
std::ofstream enginePluginsTable(enginePluginsTableFile.c_str());
if (!enginePluginsTable) {
error("Could not open \"" + enginePluginsTableFile + "\" for writing");
}
enginePluginsTable << "/* This file is automatically generated by create_project */\n"
<< "/* DO NOT EDIT MANUALLY */\n"
<< "// This file is being included by \"base/plugins.cpp\"\n";
for (EngineDescList::const_iterator i = setup.engines.begin(), end = setup.engines.end(); i != end; ++i) {
// We ignore all sub engines here because they require no special
// handling.
if (isSubEngine(i->name, setup.engines)) {
continue;
}
// Make the engine name all uppercase.
std::string engineName;
std::transform(i->name.begin(), i->name.end(), std::back_inserter(engineName), toupper);
enginePluginsTable << "#if PLUGIN_ENABLED_STATIC(" << engineName << ")\n"
<< "LINK_PLUGIN(" << engineName << ")\n"
<< "#endif\n";
}
}
} // End of anonymous namespace } // End of anonymous namespace
void error(const std::string &message) { void error(const std::string &message) {

View file

@ -102,16 +102,17 @@ struct EngineDesc {
typedef std::list<EngineDesc> EngineDescList; typedef std::list<EngineDesc> EngineDescList;
/** /**
* This function parses the project configure file and creates a list * This function parses the project directory and creates a list of
* of available engines. * available engines.
* *
* It will also automatically setup the default build state (enabled * It will also automatically setup the default build state (enabled
* or disabled) to the state specified in the "configure" file. * or disabled) to the state specified in the individual configure.engine
* files.
* *
* @param srcDir Path to the root of the project source. * @param srcDir Path to the root of the project source.
* @return List of available engines. * @return List of available engines.
*/ */
EngineDescList parseConfigure(const std::string &srcDir); EngineDescList parseEngines(const std::string &srcDir);
/** /**
* Checks whether the specified engine is a sub engine. To determine this * Checks whether the specified engine is a sub engine. To determine this
@ -262,6 +263,22 @@ void NORETURN_PRE error(const std::string &message) NORETURN_POST;
namespace CreateProjectTool { namespace CreateProjectTool {
/**
* Structure for describing an FSNode. This is a very minimalistic
* description, which includes everything we need.
* It only contains the name of the node and whether it is a directory
* or not.
*/
struct FSNode {
FSNode() : name(), isDirectory(false) {}
FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {}
std::string name; ///< Name of the file system node
bool isDirectory; ///< Whether it is a directory or not
};
typedef std::list<FSNode> FileList;
/** /**
* Gets a proper sequence of \t characters for the given * Gets a proper sequence of \t characters for the given
* indentation level. * indentation level.
@ -314,6 +331,15 @@ bool producesObjectFile(const std::string &fileName);
*/ */
std::string toString(int num); std::string toString(int num);
/**
* Returns a list of all files and directories in the specified
* path.
*
* @param dir Directory which should be listed.
* @return List of all children.
*/
FileList listDirectory(const std::string &dir);
/** /**
* Structure representing a file tree. This contains two * Structure representing a file tree. This contains two
* members: name and children. "name" holds the name of * members: name and children. "name" holds the name of
@ -474,6 +500,15 @@ protected:
* @return A new UUID as string. * @return A new UUID as string.
*/ */
std::string createUUID() const; std::string createUUID() const;
private:
/**
* This creates the engines/plugins_table.h file required for building
* ScummVM.
*
* @param setup Description of the desired build.
*/
void createEnginePluginsTable(const BuildSetup &setup);
}; };
} // End of CreateProjectTool namespace } // End of CreateProjectTool namespace