diff --git a/README.md b/README.md index 3cedf3e..04859c9 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,46 @@ cd cpp-generator The generator binary will be available at `build/bin/logos-cpp-generator`. +## Usage + +### Code Generator + +The `logos-cpp-generator` tool generates C++ wrapper code for Logos plugins. + +#### Basic Usage + +```bash +# Generate wrapper for a single plugin (uses default output directory) +logos-cpp-generator /path/to/plugin.dylib + +# Specify custom output directory +logos-cpp-generator /path/to/plugin.dylib --output-dir /custom/output/path +``` + +#### Generate from Metadata + +```bash +# List dependencies from metadata.json +logos-cpp-generator --metadata /path/to/metadata.json + +# Generate wrappers for all dependencies +logos-cpp-generator --metadata /path/to/metadata.json --module-dir /path/to/modules + +# Generate with custom output directory +logos-cpp-generator --metadata /path/to/metadata.json --module-dir /path/to/modules --output-dir /custom/output +``` + +#### Output Directory + +- **Default:** If `--output-dir` is not specified, generated files are placed in `logos-cpp-sdk/cpp/generated/` +- **Custom:** Use `--output-dir` to specify any directory for the generated files +- The output directory will be created automatically if it doesn't exist + +Generated files include: +- `_api.h` and `_api.cpp` - Wrapper code for each module +- `core_manager_api.h` and `core_manager_api.cpp` - Core manager wrapper +- `logos_sdk.h` and `logos_sdk.cpp` - Umbrella headers including all modules + ### Requirements #### Build Tools diff --git a/cpp-generator/main.cpp b/cpp-generator/main.cpp index 8b604cb..2941d53 100644 --- a/cpp-generator/main.cpp +++ b/cpp-generator/main.cpp @@ -605,7 +605,7 @@ static bool writeUmbrellaSource(const QString& genDirPath, QTextStream& err) return true; } -static int generateFromPlugin(const QString& pluginInputPath, QTextStream& out, QTextStream& err) +static int generateFromPlugin(const QString& pluginInputPath, const QString& outputDir, QTextStream& out, QTextStream& err) { QFileInfo fi(pluginInputPath); if (!fi.exists()) { @@ -618,7 +618,7 @@ static int generateFromPlugin(const QString& pluginInputPath, QTextStream& out, resolvedPath = fi.absoluteFilePath(); } - QString genDirPath = QDir::current().filePath("logos-cpp-sdk/cpp/generated"); + QString genDirPath = outputDir.isEmpty() ? QDir::current().filePath("logos-cpp-sdk/cpp/generated") : outputDir; QDir().mkpath(genDirPath); if (!ensureCoreManagerWrapper(genDirPath, err)) { return 9; @@ -689,7 +689,7 @@ static int generateFromPlugin(const QString& pluginInputPath, QTextStream& out, QJsonDocument doc(methods); // out << doc.toJson(QJsonDocument::Indented) << "\n"; - out << "Generated: logos-cpp-sdk/cpp/generated/" << headerRel << " and logos-cpp-sdk/cpp/generated/" << sourceRel << "\n"; + out << "Generated: " << QDir(genDirPath).filePath(headerRel) << " and " << QDir(genDirPath).filePath(sourceRel) << "\n"; out.flush(); loader.unload(); @@ -703,13 +703,24 @@ int main(int argc, char* argv[]) QTextStream err(stderr); QTextStream out(stdout); + const QStringList args = app.arguments(); + + // Parse --output-dir option + QString outputDir; + const int outDirIdx = args.indexOf("--output-dir"); + if (outDirIdx != -1 && outDirIdx + 1 < args.size()) { + outputDir = args.at(outDirIdx + 1); + if (outputDir.startsWith('@')) { + outputDir.remove(0, 1); + } + } + // Support: extract dependencies from a metadata.json file { - const QStringList args = app.arguments(); const int metaIdx = args.indexOf("--metadata"); if (metaIdx != -1) { if (metaIdx + 1 >= args.size()) { - err << "Usage: " << QFileInfo(app.applicationFilePath()).fileName() << " --metadata /absolute/path/to/metadata.json\n"; + err << "Usage: " << QFileInfo(app.applicationFilePath()).fileName() << " --metadata /absolute/path/to/metadata.json [--output-dir /path/to/output]\n"; return 1; } QString metaPathArg = args.at(metaIdx + 1); @@ -745,7 +756,7 @@ int main(int argc, char* argv[]) const int modDirIdx = args.indexOf("--module-dir"); if (modDirIdx != -1) { if (modDirIdx + 1 >= args.size()) { - err << "Usage: " << QFileInfo(app.applicationFilePath()).fileName() << " --metadata /path/to/metadata.json --module-dir /path/to/modules_dir\n"; + err << "Usage: " << QFileInfo(app.applicationFilePath()).fileName() << " --metadata /path/to/metadata.json --module-dir /path/to/modules_dir [--output-dir /path/to/output]\n"; return 1; } QString moduleDirArg = args.at(modDirIdx + 1); @@ -758,7 +769,7 @@ int main(int argc, char* argv[]) return 2; } - QString genDirPath = QDir::current().filePath("logos-cpp-sdk/cpp/generated"); + QString genDirPath = outputDir.isEmpty() ? QDir::current().filePath("logos-cpp-sdk/cpp/generated") : outputDir; QDir().mkpath(genDirPath); if (!ensureCoreManagerWrapper(genDirPath, err)) { return 9; @@ -786,7 +797,7 @@ int main(int argc, char* argv[]) continue; } out << "Running generator for dependency plugin: " << pluginPath << "\n"; - const int st = generateFromPlugin(pluginPath, out, err); + const int st = generateFromPlugin(pluginPath, outputDir, out, err); if (st != 0) { overallStatus = st; // remember last non-zero } @@ -811,12 +822,12 @@ int main(int argc, char* argv[]) } } - if (app.arguments().size() < 2) { - err << "Usage: " << QFileInfo(app.applicationFilePath()).fileName() << " /absolute/path/to/plugin\n"; - err << " or: " << QFileInfo(app.applicationFilePath()).fileName() << " --metadata /absolute/path/to/metadata.json\n"; + if (args.size() < 2) { + err << "Usage: " << QFileInfo(app.applicationFilePath()).fileName() << " /absolute/path/to/plugin [--output-dir /path/to/output]\n"; + err << " or: " << QFileInfo(app.applicationFilePath()).fileName() << " --metadata /absolute/path/to/metadata.json [--output-dir /path/to/output]\n"; return 1; } - QString argPath = app.arguments().at(1); - return generateFromPlugin(argPath, out, err); + QString argPath = args.at(1); + return generateFromPlugin(argPath, outputDir, out, err); }