diff --git a/commandLine/src/main.cpp b/commandLine/src/main.cpp index 0b52c20d..7fc1ef1f 100644 --- a/commandLine/src/main.cpp +++ b/commandLine/src/main.cpp @@ -31,7 +31,8 @@ enum optionIndex { UNKNOWN, COMMAND, BACKUP_PROJECT_FILES, FRAMEWORKS, - CLEANNAME_DISABLE + CLEANNAME_DISABLE, + DEFINES }; constexpr option::Descriptor usage[] = { @@ -58,6 +59,8 @@ constexpr option::Descriptor usage[] = { { CLEANNAME_DISABLE, 0, "n", "cleanname", option::Arg::Optional, " --cleanname, -f \tcleanname" }, + { DEFINES, 0, "D", "defines", option::Arg::Optional, " --defines, -D \tpreprocessor defines list (such as OF_USE_ANGLE=1,MY_FLAG)" }, + { 0, 0, 0, 0, 0, 0 } }; @@ -84,6 +87,7 @@ vector addons; vector srcPaths; vector targets; vector frameworks; +vector defines; string ofPathEnv; string templateName; @@ -267,6 +271,14 @@ void updateProject(const fs::path & path, const string & target, bool bConsiderP project->addFramework(f, "Frameworks", true); } + // matches addAddonDefines()'s existing convention (single call, default RELEASE_LIB) - + // xcodeProject::addDefine ignores libType and applies to all build configs anyway, + // but visualStudioProject::addDefine doesn't, so a define here is Release-only for VS, + // consistent with how addon-provided defines already behave there + for (auto & d : defines) { + project->addProjectDefine(d); + } + for (auto & srcPath : srcPaths) { project->addSrcRecursively(srcPath); } @@ -583,6 +595,10 @@ int main(int argc, char ** argv) { } } + if (options[DEFINES].count() > 0 && options[DEFINES].arg != NULL) { + defines = ofSplitString(options[DEFINES].arg, ",", true, true); + } + if (parse.nonOptionsCount() > 0) { projectName = parse.nonOption(0); @@ -734,6 +750,10 @@ int main(int argc, char ** argv) { project->addFramework(f, "Frameworks", true); } + for (auto & d : defines) { + project->addProjectDefine(d); + } + for (auto & s : srcPaths) { project->addSrcRecursively(s); } diff --git a/commandLine/src/projects/baseProject.h b/commandLine/src/projects/baseProject.h index 4f4cd18a..f5f8e13a 100644 --- a/commandLine/src/projects/baseProject.h +++ b/commandLine/src/projects/baseProject.h @@ -98,6 +98,11 @@ class baseProject { virtual void addFramework(const fs::path & path, const fs::path & folder, bool isRelativeToSDK = false){}; + // public entry point for project-level preprocessor defines (e.g. -D/--defines on the + // CLI, or a GUI-driven renderer choice) - addDefine() itself stays protected since it's + // also invoked internally by addAddonDefines() for addon-provided defines + void addProjectDefine(const std::string & define, LibType libType = RELEASE_LIB) { addDefine(define, libType); } + #ifdef OFADDON_OUTPUT_JSON_DEBUG void saveAddonsToJson(){ diff --git a/commandLine/src/projects/xcodeProject.cpp b/commandLine/src/projects/xcodeProject.cpp index efbc508f..73b380a8 100644 --- a/commandLine/src/projects/xcodeProject.cpp +++ b/commandLine/src/projects/xcodeProject.cpp @@ -962,7 +962,13 @@ bool xcodeProject::saveProjectFile() { // alert (c, 31); // cout << "this is not array, creating" << endl; // cout << thispath << endl; - auto v { j[p] }; + // NOTE: must be copy-init (=), not brace-init ({}) - nlohmann::json's + // initializer_list constructor wraps a single json value in an array, + // so `auto v { j[p] }` on a null j[p] makes v == [null] rather than + // null, and that gets pushed into the array below instead of being + // correctly skipped, corrupting every freshly-created array key with a + // leading [null] element (e.g. GCC_PREPROCESSOR_DEFINITIONS via addDefine) + auto v = j[p]; j[p] = json::array(); if (!v.is_null()) { // cout << "thispath " << thispath << endl; diff --git a/frontend/app.js b/frontend/app.js index 94b7987b..f93658eb 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -958,6 +958,9 @@ function setup() { ipcRenderer.send('setLanguage', lang); }); + $('#rendererDropdown').dropdown(); + $('#rendererDropdown').dropdown('set exactly', 'default'); + // reflesh template dropdown list depends on selected platforms $("#platformsDropdown").on('change', () => { const selectedPlatforms = $("#platformsDropdown input").val(); @@ -969,6 +972,15 @@ function setup() { } console.log(arg); ipcRenderer.send('refreshTemplateList', arg); + + // renderer choice (OF_USE_ANGLE / OF_USE_DAWN) only applies to the Xcode-based + // osx/ios/macos (mega iOS/tvOS/macOS) targets + const rendererPlatforms = ['osx', 'ios', 'macos']; + if (selectedPlatformArray.some((p) => rendererPlatforms.includes(p))) { + $('#rendererField').show(); + } else { + $('#rendererField').hide(); + } }) $("#platformsDropdownMulti").on('change', () => { const selectedPlatforms = $("#platformsDropdownMulti input").val(); @@ -1151,6 +1163,18 @@ function generate() { const lengthOfPlatforms = platformValueArray.length; + // renderer choice adds its OF_USE_* define on top of whatever the user typed manually + const rendererDefines = { + angle: 'OF_USE_ANGLE=1', + dawn: 'OF_USE_DAWN=1' + }; + const rendererChoice = $('#rendererDropdown').dropdown('get value'); + const customDefinesText = $('#customDefines').val().trim(); + const definesArr = customDefinesText ? customDefinesText.split(',').map((s) => s.trim()).filter(Boolean) : []; + if (rendererDefines[rendererChoice]) { + definesArr.push(rendererDefines[rendererChoice]); + } + const gen = { projectName: $("#projectName").val(), projectPath: $("#projectPath").val(), @@ -1159,7 +1183,8 @@ function generate() { templateList: templateValueArray, addonList: addonValueArray, //$("#addonsDropdown").val(); ofPath: $("#ofPath").val(), - verbose: bVerbose + verbose: bVerbose, + defines: definesArr.join(',') }; // console.log(gen); diff --git a/frontend/index.html b/frontend/index.html index 97c2f301..a6a5d41f 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -228,6 +228,29 @@
+ +
+ +
+ +
+