From 6195873ac3c8d34803b54a1dabe78bf1b0271812 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Sat, 31 Oct 2026 12:58:13 +1100 Subject: [PATCH 1/4] System frameworks / libraries for macOS, iOS, tvOS kept in config.make, GUI fields and help tab --- commandLine/readme.md | 20 ++++ commandLine/src/main.cpp | 27 ++++-- commandLine/src/projects/baseProject.cpp | 107 ++++++++++++++++++++++ commandLine/src/projects/baseProject.h | 9 ++ commandLine/src/projects/xcodeProject.cpp | 11 +++ commandLine/src/projects/xcodeProject.h | 2 + frontend/app.js | 15 ++- frontend/index.html | 72 +++++++++++++++ frontend/index.js | 33 +++++++ frontend/locales/de.json | 5 + frontend/locales/en.json | 5 + frontend/locales/es.json | 5 + frontend/locales/fr.json | 5 + frontend/locales/ja.json | 5 + frontend/locales/ko.json | 5 + frontend/locales/pt.json | 5 + frontend/locales/ru.json | 5 + frontend/locales/zh-CN.json | 5 + 18 files changed, 331 insertions(+), 10 deletions(-) diff --git a/commandLine/readme.md b/commandLine/readme.md index a22dafdf..e95197a2 100644 --- a/commandLine/readme.md +++ b/commandLine/readme.md @@ -26,6 +26,12 @@ here's the extended options if you want to experiment. please take are that opt -v, --verbose run verbose -t"project_template", --template="project_template" project template -d, --dryrun don't change files + -f"frameworks", --frameworks="frameworks" Apple system frameworks + (Security,CoreBluetooth) + --system-libs="libraries" Apple system libraries + (sqlite3,z) + + run with --help for every option. **note that on windows, command line flags are written with "/" not "-" and don't have abbreviations, so -r would be /recursive** @@ -60,6 +66,20 @@ you can also specify platforms (default platform is inferred) such as: ./projectGenerator -o"pathToOF" -p"ios" pathOfNewIOSProject +## System frameworks and libraries (macOS / iOS / tvOS) + +Link SDK frameworks and libraries (sqlite3 = `libsqlite3.tbd`) to a project: + + ./projectGenerator -o"pathToOF" -p"osx" -f"Security,CoreBluetooth" --system-libs="sqlite3,z" pathToProject + +`libsqlite3`, `libsqlite3.tbd`, `-lsqlite3` and `Security.framework` work too. They are saved with the project in `config.make`: + + PROJECT_FRAMEWORKS = Security CoreBluetooth + PROJECT_SYSTEM_LIBS = sqlite3 z + +and read back on every update, so a plain `./projectGenerator -o"pathToOF" pathToProject` keeps them. The Xcode project gets them in Link Binary With Libraries; the makefiles and CMake read the same lines (`-framework Security` on Apple only, `-lsqlite3` everywhere). Edit `config.make` and update the project, or pass an empty `-f` / `--system-libs=` to remove them. + +The GUI shows them as System frameworks / System libraries when an Apple platform is selected (see the help tab). diff --git a/commandLine/src/main.cpp b/commandLine/src/main.cpp index 23e50268..883d94f9 100644 --- a/commandLine/src/main.cpp +++ b/commandLine/src/main.cpp @@ -32,6 +32,7 @@ enum optionIndex { UNKNOWN, COMMAND, BACKUP_PROJECT_FILES, FRAMEWORKS, + SYSTEMLIBS, CLEANNAME_DISABLE, DEFINES, POSTBUILD, @@ -61,7 +62,8 @@ constexpr option::Descriptor usage[] = { { COMMAND, 0, "c", "command", option::Arg::None, " --command, -c \truns command" }, { BACKUP_PROJECT_FILES, 0, "b", "backup", option::Arg::None, " --backup, -b \tbackup project files when replacing with template" }, - { FRAMEWORKS, 0, "f", "frameworks", option::Arg::Optional, " --frameworks, -f \tframeworks list (such as Vision,ARKit)" }, + { FRAMEWORKS, 0, "f", "frameworks", option::Arg::Optional, " --frameworks, -f \tApple system frameworks (such as Security,CoreBluetooth), saved in config.make PROJECT_FRAMEWORKS. Empty removes them" }, + { SYSTEMLIBS, 0, "", "system-libs", option::Arg::Optional, " --system-libs \tApple system libraries (such as sqlite3,z = libsqlite3.tbd, libz.tbd), saved in config.make PROJECT_SYSTEM_LIBS. Empty removes them" }, { CLEANNAME_DISABLE, 0, "n", "cleanname", option::Arg::Optional, " --cleanname, -f \tcleanname" }, @@ -98,6 +100,9 @@ vector addons; vector srcPaths; vector targets; vector frameworks; +bool bFrameworksPassedIn = false; +vector systemLibs; +bool bSystemLibsPassedIn = false; vector defines; string postBuildScript; string emscriptenWasm; // empty keeps the project's config.make value @@ -276,6 +281,7 @@ void updateProject(const fs::path & path, const string & target, bool bConsiderP project->setMsys2Environment(msys2Env); project->setEmscriptenWasm(emscriptenWasm); project->setAppVersion(appVersion, appBuild); + project->setSystemFrameworks(frameworks, bFrameworksPassedIn, systemLibs, bSystemLibsPassedIn); project->create(path, templateName); if (bConsiderParameterAddons && bAddonsPassedIn) { @@ -286,9 +292,7 @@ void updateProject(const fs::path & path, const string & target, bool bConsiderP ofLogNotice() << "parsing addons.make"; project->parseAddons(); } - for (auto & f : frameworks) { - project->addFramework(f, "Frameworks", true); - } + project->addSystemFrameworks(); // all build configs (visualStudioProject overrides addProjectDefine for Debug + Release) for (auto & d : defines) { @@ -624,10 +628,16 @@ int pgMain(int argc, char ** argv) { #endif if (options[FRAMEWORKS].count() > 0) { - bAddonsPassedIn = true; // could be empty + bFrameworksPassedIn = true; // could be empty if (options[FRAMEWORKS].arg != NULL) { frameworks = ofSplitString(options[FRAMEWORKS].arg, ",", true, true); -// cout << "frameworks " << options[FRAMEWORKS].arg << endl; + } + } + + if (options[SYSTEMLIBS].count() > 0) { + bSystemLibsPassedIn = true; // could be empty + if (options[SYSTEMLIBS].arg != NULL) { + systemLibs = ofSplitString(options[SYSTEMLIBS].arg, ",", true, true); } } @@ -807,6 +817,7 @@ int pgMain(int argc, char ** argv) { project->setMsys2Environment(msys2Env); project->setEmscriptenWasm(emscriptenWasm); project->setAppVersion(appVersion, appBuild); + project->setSystemFrameworks(frameworks, bFrameworksPassedIn, systemLibs, bSystemLibsPassedIn); project->create(projectPath, templateName); if(bAddonsPassedIn){ for (auto & addon : addons) { @@ -815,9 +826,7 @@ int pgMain(int argc, char ** argv) { }else{ project->parseAddons(); } - for (auto & f : frameworks) { - project->addFramework(f, "Frameworks", true); - } + project->addSystemFrameworks(); for (auto & d : defines) { project->addProjectDefine(d); diff --git a/commandLine/src/projects/baseProject.cpp b/commandLine/src/projects/baseProject.cpp index 14452258..18bfe916 100644 --- a/commandLine/src/projects/baseProject.cpp +++ b/commandLine/src/projects/baseProject.cpp @@ -129,6 +129,51 @@ static std::string readEmscriptenWasm(const fs::path & configMake) { return bits; } +// space separated list from config.make, VAR = a b / VAR += c +static std::vector readMakeList(const fs::path & configMake, const std::string & name) { + std::vector values; + if (!fs::exists(configMake)) return values; + for (auto & line : fileToStrings(configMake)) { + auto config = ofTrim(line); + if (config.empty() || config[0] == '#') continue; + auto eq = config.find('='); + if (eq == std::string::npos) continue; + auto var = ofTrim(config.substr(0, eq)); + bool append = !var.empty() && var.back() == '+'; + if (!var.empty() && (var.back() == '?' || var.back() == '+' || var.back() == ':')) var = ofTrim(var.substr(0, var.size() - 1)); + if (var != name) continue; + if (!append) values.clear(); + for (auto & v : ofSplitString(ofTrim(config.substr(eq + 1)), " ", true, true)) values.emplace_back(v); + } + return values; +} + +// Security.framework -> Security +static std::string cleanFrameworkName(std::string name) { + name = ofTrim(name); + if (name.size() > 10 && name.substr(name.size() - 10) == ".framework") name = name.substr(0, name.size() - 10); + return name; +} + +// -lsqlite3 / libsqlite3 / libsqlite3.tbd / libsqlite3.dylib -> sqlite3 +static std::string cleanSystemLibName(std::string name) { + name = ofTrim(name); + if (name.rfind("-l", 0) == 0) name = name.substr(2); + for (std::string ext : { ".tbd", ".dylib" }) { + if (name.size() > ext.size() && name.substr(name.size() - ext.size()) == ext) name = name.substr(0, name.size() - ext.size()); + } + if (name.rfind("lib", 0) == 0 && name.size() > 3) name = name.substr(3); + return name; +} + +static bool isSystemLibName(const std::string & name) { + return name.rfind("-l", 0) == 0 || name.rfind("lib", 0) == 0 || ofIsStringInString(name, ".tbd") || ofIsStringInString(name, ".dylib"); +} + +static void addUnique(std::vector & list, const std::string & value) { + if (!value.empty() && std::find(list.begin(), list.end(), value) == list.end()) list.emplace_back(value); +} + static const std::string OF_CMAKE_INCLUDE { "libs/openFrameworksCompiled/project/CMake/openFrameworks.cmake" }; // set(PROJECT_EMSCRIPTEN_WASM 64) written by PG into an openFrameworks CMakeLists.txt (openFrameworks#8586) @@ -252,6 +297,18 @@ bool baseProject::create(const fs::path & _path, string templateName){ ofLogNotice() << "{ \"emscriptenWasm\": \"" << emscriptenWasm << "\" }"; } + systemFrameworks.clear(); + systemLibs.clear(); + for (auto & f : systemFrameworksPassed ? systemFrameworksOption : readMakeList(projectDir / "config.make", "PROJECT_FRAMEWORKS")) { + if (isSystemLibName(f)) addUnique(systemLibs, cleanSystemLibName(f)); + else addUnique(systemFrameworks, cleanFrameworkName(f)); + } + for (auto & l : systemLibsPassed ? systemLibsOption : readMakeList(projectDir / "config.make", "PROJECT_SYSTEM_LIBS")) { + addUnique(systemLibs, cleanSystemLibName(l)); + } + if (systemFrameworks.size()) ofLogNotice() << "{ \"systemFrameworks\": \"" << ofJoinString(systemFrameworks, " ") << "\" }"; + if (systemLibs.size()) ofLogNotice() << "{ \"systemLibs\": \"" << ofJoinString(systemLibs, " ") << "\" }"; + // app version / build: config.make first, then CMakeLists, Xcode, Android; the CLI value wins { std::vector>> found { @@ -427,6 +484,28 @@ bool baseProject::save(){ bool bWroteWasm = false; bool bWroteAppVersion = false; bool bWroteAppBuild = false; + bool bWroteFrameworks = false; + bool bWroteSystemLibs = false; + auto isMakeVar = [](const std::string & line, const std::string & name) { + auto config = ofTrim(line); + if (config.rfind("#", 0) == 0) config = ofTrim(config.substr(1)); + if (config.rfind(name, 0) != 0) return false; + auto rest = ofTrim(config.substr(name.size())); + return rest.rfind("=", 0) == 0 || rest.rfind("+=", 0) == 0 || rest.rfind(":=", 0) == 0 || rest.rfind("?=", 0) == 0; + }; + // the list on the first line, commented when empty, later += lines are folded in + auto writeMakeList = [&](const std::string & line, const std::string & name, const std::vector & values, bool & bWrote) { + if (bWrote) { + if (ofTrim(line).rfind("#", 0) == 0) saveConfig << line << std::endl; + return; + } + if (values.empty()) { + saveConfig << (ofTrim(line).rfind("#", 0) == 0 ? line : "# " + name + " =") << std::endl; + } else { + saveConfig << name << " = " << ofJoinString(values, " ") << std::endl; + } + bWrote = true; + }; for (auto & str : lines) { //add the of root path @@ -472,6 +551,12 @@ bool baseProject::save(){ bWroteAppBuild = true; } } + else if( isMakeVar(str, "PROJECT_FRAMEWORKS") ){ + writeMakeList(str, "PROJECT_FRAMEWORKS", systemFrameworks, bWroteFrameworks); + } + else if( isMakeVar(str, "PROJECT_SYSTEM_LIBS") ){ + writeMakeList(str, "PROJECT_SYSTEM_LIBS", systemLibs, bWroteSystemLibs); + } else if( emscriptenWasm == "32" && str.rfind("EMSCRIPTEN_MEMORY64", 0) == 0 ){ saveConfig << "# " << str << std::endl; } else { @@ -490,6 +575,12 @@ bool baseProject::save(){ if (!bWroteAppVersion) saveConfig << "APP_VERSION = " << appVersion << std::endl; if (!bWroteAppBuild) saveConfig << "APP_BUILD = " << appBuild << std::endl; } + if ((systemFrameworks.size() && !bWroteFrameworks) || (systemLibs.size() && !bWroteSystemLibs)) { + if (lines.size()) saveConfig << std::endl; + saveConfig << "# system frameworks (Security) and libraries (sqlite3 = libsqlite3.tbd / -lsqlite3)" << std::endl; + if (systemFrameworks.size() && !bWroteFrameworks) saveConfig << "PROJECT_FRAMEWORKS = " << ofJoinString(systemFrameworks, " ") << std::endl; + if (systemLibs.size() && !bWroteSystemLibs) saveConfig << "PROJECT_SYSTEM_LIBS = " << ofJoinString(systemLibs, " ") << std::endl; + } saveConfig.close(); saveCMakeLists(); saveAppVersionFiles(); @@ -1010,6 +1101,22 @@ void baseProject::parseConfigMake(){ } } +void baseProject::setSystemFrameworks(const std::vector & frameworks, bool frameworksPassed, const std::vector & libs, bool libsPassed) { + systemFrameworksOption = frameworks; + systemFrameworksPassed = frameworksPassed; + systemLibsOption = libs; + systemLibsPassed = libsPassed; +} + +void baseProject::addSystemFrameworks() { + for (auto & f : systemFrameworks) { + addFramework(f, "Frameworks", true); + } + for (auto & l : systemLibs) { + addSystemLibrary(l); + } +} + void baseProject::recursiveTemplateCopy(const fs::path & srcDir, const fs::path & destDir){ if (recursiveCopy(srcDir, destDir)) { fs::path templateFile = destDir / "template.config"; diff --git a/commandLine/src/projects/baseProject.h b/commandLine/src/projects/baseProject.h index 2df1c72f..16e4b07b 100644 --- a/commandLine/src/projects/baseProject.h +++ b/commandLine/src/projects/baseProject.h @@ -97,6 +97,12 @@ class baseProject { bool bOverwrite = true; virtual void addFramework(const fs::path & path, const fs::path & folder, bool isRelativeToSDK = false){}; + // SDK library like sqlite3 = usr/lib/libsqlite3.tbd (Xcode only) + virtual void addSystemLibrary(const std::string & name){}; + + // system frameworks / libraries (-f / --system-libs), kept in config.make PROJECT_FRAMEWORKS / PROJECT_SYSTEM_LIBS + void setSystemFrameworks(const std::vector & frameworks, bool frameworksPassed, const std::vector & libs, bool libsPassed); + void addSystemFrameworks(); // 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 @@ -185,6 +191,9 @@ class baseProject { std::vector extSrcPaths; std::vector projectDefines; // also written to config.make PROJECT_DEFINES for make builds std::vector missingAddons; // not found, still written to addons.make (#258) + std::vector systemFrameworks, systemLibs; // value for this project + std::vector systemFrameworksOption, systemLibsOption; // from the CLI + bool systemFrameworksPassed = false, systemLibsPassed = false; // false = keep the project's std::string emscriptenWasmOption; // from the CLI, empty = keep std::string emscriptenWasm; // value for this project: "", "32" or "64" void saveCMakeLists(); diff --git a/commandLine/src/projects/xcodeProject.cpp b/commandLine/src/projects/xcodeProject.cpp index cc610b54..3a4c3daa 100644 --- a/commandLine/src/projects/xcodeProject.cpp +++ b/commandLine/src/projects/xcodeProject.cpp @@ -666,6 +666,17 @@ void xcodeProject::addFramework(const fs::path & path, const fs::path & folder, } } +void xcodeProject::addSystemLibrary(const std::string & name) { + ofLogVerbose() << "Adding system library " << name; + addCommand("# ----- addSystemLibrary " + name); + + fileProperties fp; + fp.absolute = false; + fp.isRelativeToSDK = true; + fp.linkBinaryWithLibraries = true; + addFile(fs::path { "usr/lib/lib" + name + ".tbd" }, "Frameworks", fp); +} + void xcodeProject::addDylib(const fs::path & path, const fs::path & folder) { // alert( "xcodeProject::addDylib " + ofPathToString(path) , 33); diff --git a/commandLine/src/projects/xcodeProject.h b/commandLine/src/projects/xcodeProject.h index 890889fe..fb9d78eb 100644 --- a/commandLine/src/projects/xcodeProject.h +++ b/commandLine/src/projects/xcodeProject.h @@ -55,6 +55,7 @@ class xcodeProject : public baseProject { void addCompileFlagsForMMFile(const fs::path & srcFile); void addFramework(const fs::path & path, const fs::path & folder, bool isRelativeToSDK = false) override; + void addSystemLibrary(const std::string & name) override; void addXCFramework(const fs::path & path, const fs::path & folder); void addDylib(const fs::path & path, const fs::path & folder); @@ -125,6 +126,7 @@ class xcodeProject : public baseProject { { ".framework" , "wrapper.framework" }, { ".xcframework" , "wrapper.xcframework" }, { ".dylib" , "compiled.mach-o.dylib" }, + { ".tbd" , "sourcecode.text-based-dylib-definition" }, { ".cpp" , "sourcecode.cpp.cpp" }, { ".c" , "sourcecode.cpp.c" }, diff --git a/frontend/app.js b/frontend/app.js index b0f821ab..0fc8979c 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -218,6 +218,8 @@ ipcRenderer.on('setGenerateMode', (event, arg) => { $('#appVersion').val(''); $('#appBuild').val(''); $('#appVersionNote').hide(); + $('#systemFrameworks').val(''); + $('#systemLibs').val(''); } }); @@ -230,6 +232,13 @@ ipcRenderer.on('setAppVersion', (event, { version, build, differs }) => { $('#appVersionNote').text(note).toggle(!!defaultSettings.advancedMode && note.length > 0); }); +//------------------------------------------- +// existing project's config.make PROJECT_FRAMEWORKS / PROJECT_SYSTEM_LIBS, so updating keeps them +ipcRenderer.on('setSystemFrameworks', (event, { frameworks, libs }) => { + $('#systemFrameworks').val((frameworks || []).join(',')); + $('#systemLibs').val((libs || []).join(',')); +}); + //------------------------------------------- // existing project's PROJECT_EMSCRIPTEN_WASM, so updating keeps it ipcRenderer.on('setEmscriptenWasm', (event, bits) => { @@ -1276,7 +1285,10 @@ function generate() { msys2Env: $('#msys2EnvField').css('display') !== 'none' ? $('#msys2EnvDropdown').dropdown('get value') : '', emscriptenWasm: $('#wasmField').css('display') !== 'none' ? $('#wasmDropdown').dropdown('get value') : '', appVersion: $('#appVersion').val().trim(), - appBuild: $('#appBuild').val().trim() + appBuild: $('#appBuild').val().trim(), + // only for Apple targets; hidden = keep the project's config.make values + systemFrameworks: $('#systemFrameworksField').css('display') !== 'none' ? $('#systemFrameworks').val().split(',').map((s) => s.trim()).filter(Boolean) : null, + systemLibs: $('#systemFrameworksField').css('display') !== 'none' ? $('#systemLibs').val().split(',').map((s) => s.trim()).filter(Boolean) : null }; // console.log(gen); @@ -1469,6 +1481,7 @@ function updateRendererFieldVisibility() { // advanced only; hidden fields keep the project's values, so updating still keeps them $('#appVersionField').css('display', defaultSettings.advancedMode ? 'flex' : 'none'); $('#appVersionNote').toggle(!!defaultSettings.advancedMode && $('#appVersionNote').text().length > 0); + $('#systemFrameworksField').css('display', selectedPlatforms.some((p) => ['osx', 'ios', 'macos', 'tvos'].includes(p)) ? 'flex' : 'none'); const glPlatforms = ['osx', 'vs', 'msys2', 'linux', 'linux64', 'linuxarmv6l', 'linuxarmv7l', 'linuxaarch64', 'vscode']; $('#glField').toggle(!!defaultSettings.advancedMode && selectedPlatforms.some((p) => glPlatforms.includes(p))); diff --git a/frontend/index.html b/frontend/index.html index e82f7490..5e4a0038 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -75,6 +75,16 @@ word-wrap: break-word; } + #helpTab .helpCode { + background-color: #333; + color: #dfdfdf; + padding: 8px 10px; + border-radius: 4px; + font-size: 11px; + white-space: pre-wrap; + word-break: break-all; + } + @@ -108,6 +118,9 @@
downloads
+ +
help
+
@@ -305,6 +318,24 @@ +
+ +
+

Create a project

+

Set the project name and path, pick the addons and platforms, then press Generate. New projects start from the template's src/ (main.cpp, ofApp.h, ofApp.cpp).

+ +

Update a project

+

Drag the project folder onto the window, or set its name and path. The PG switches to Update and reads the project's settings back:

+
    +
  • addons.make - one addon per line. Addons that aren't installed are kept and shown so you can download or find them.
  • +
  • config.make - OF path, extra source paths, defines, app version / build, system frameworks and libraries.
  • +
+

Update multiple (advanced options) updates every project in a folder, e.g. all of examples/.

+ +

Platforms and templates

+

The PG targets this computer's platform (on macOS: osx). With Advanced options on in settings, pick one or more platforms (Xcode, Visual Studio, make, VS Code, Android, Emscripten ...) and templates, which add to them, e.g. VS Code on top of osx or vs.

+ +

System frameworks and libraries (macOS / iOS / tvOS)

+

When an Apple platform is selected, add SDK frameworks and libraries the project links to, comma-separated:

+
    +
  • System frameworks: Security,CoreBluetooth - Security.framework, CoreBluetooth.framework
  • +
  • System libraries: sqlite3,z - libsqlite3.tbd, libz.tbd (libsqlite3, libsqlite3.tbd and -lsqlite3 also work)
  • +
+

They are saved with the project in config.make, so updating the project or opening it on another machine keeps them:

+
PROJECT_FRAMEWORKS = Security CoreBluetooth
+PROJECT_SYSTEM_LIBS = sqlite3 z
+

Xcode gets them in Link Binary With Libraries; make and CMake builds read the same lines (-framework Security, -lsqlite3). Clear a field and update to remove them.

+ +

Advanced options

+

Turn on Advanced options in settings for: custom defines, renderer (ANGLE / Dawn / GLon12), OpenGL / GLES / WebGL version, app version and build, post-build script, MSYS2 environment, Emscripten wasm32 / wasm64.

+ +

Downloads

+

Download or update the prebuilt openFrameworks libraries, or single (modular) libraries, for your OF path.

+ +

Command line

+

The PG app runs the projectGenerator command line, which can be used on its own:

+
projectGenerator -o"path/to/openFrameworks" -a"ofxGui,ofxOsc" -p"osx" "path/to/myApp"
+projectGenerator -o"path/to/openFrameworks" -p"ios" -f"Security,CoreBluetooth" --system-libs="sqlite3" "path/to/myApp"
+projectGenerator -o"path/to/openFrameworks" -r -p"osx" "path/to/examples"
+projectGenerator --help
+

Run without -a, -f or --system-libs to keep what the project's addons.make / config.make already have. An empty -f / --system-libs= removes them.

+
diff --git a/frontend/index.js b/frontend/index.js index d7d85582..56dc9ecc 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -104,6 +104,26 @@ function readProjectAppVersion(folder) { return { version, build, differs }; } +/** + * PROJECT_FRAMEWORKS / PROJECT_SYSTEM_LIBS of an existing project's config.make, read like the commandLine does. + * @param {string} folder - The project folder. + * @returns {{frameworks: Array, libs: Array}} + */ +function readProjectSystemFrameworks(folder) { + const lists = { PROJECT_FRAMEWORKS: [], PROJECT_SYSTEM_LIBS: [] }; + let text = ''; + try { + text = fs.readFileSync(path.join(folder, 'config.make'), 'utf8'); + } catch (e) { + return { frameworks: [], libs: [] }; + } + for (const m of text.matchAll(/^[ \t]*(PROJECT_FRAMEWORKS|PROJECT_SYSTEM_LIBS)[ \t]*([?:+]?)=(.*)$/gm)) { + const values = m[3].trim().split(/\s+/).filter(Boolean); + lists[m[1]] = m[2] === '+' ? lists[m[1]].concat(values) : values; + } + return { frameworks: lists.PROJECT_FRAMEWORKS, libs: lists.PROJECT_SYSTEM_LIBS }; +} + // mirrors isGoodOFPath() in commandLine/src/main.cpp function isGoodOFPath(p) { try { @@ -1011,6 +1031,7 @@ ipcMain.on('isOFProjectFolder', (event, project) => { event.sender.send('setEmscriptenWasm', '64'); } event.sender.send('setAppVersion', readProjectAppVersion(folder)); + event.sender.send('setSystemFrameworks', readProjectSystemFrameworks(folder)); } else { event.sender.send('setGenerateMode', 'createMode'); @@ -1762,6 +1783,8 @@ ipcMain.on('downloadModularLibs', async (event, { ofPath, tag, names }) => { * emscriptenWasm: string, * appVersion: string, * appBuild: string, + * systemFrameworks: Array|null, + * systemLibs: Array|null, * }} GenerateArgument */ /** @@ -1784,6 +1807,8 @@ function generateFunction(event, generate) { emscriptenWasm, appVersion, appBuild, + systemFrameworks, + systemLibs, } = generate; const args = []; @@ -1838,6 +1863,14 @@ function generateFunction(event, generate) { args.push(`--app-build=${appBuild}`); } + // null keeps the project's config.make PROJECT_FRAMEWORKS / PROJECT_SYSTEM_LIBS, empty removes them + if (Array.isArray(systemFrameworks)) { + args.push(`-f${systemFrameworks.join(',')}`); + } + if (Array.isArray(systemLibs)) { + args.push(`--system-libs=${systemLibs.join(',')}`); + } + if (projectName != null && projectPath != null) { args.push(path.join(projectPath, projectName)); } diff --git a/frontend/locales/de.json b/frontend/locales/de.json index 301aef9a..b1e6b4fb 100644 --- a/frontend/locales/de.json +++ b/frontend/locales/de.json @@ -2,6 +2,7 @@ "nav.create": "erstellen / aktualisieren", "nav.updateMultiple": "mehrere aktualisieren", "nav.ofMenu": "Downloads", + "nav.help": "Hilfe", "statusBar.targeting": "Ziel:", "statusBar.noPath": "(kein openFrameworks-Pfad festgelegt)", "field.projectName": "Projektname:", @@ -163,6 +164,10 @@ "note.wasm64": "Benötigt wasm64-Bibliotheken: BITS=64 scripts/emscripten/download_libs.sh ausführen (ersetzt die installierten lib/emscripten-Bibliotheken).", "field.appVersion": "Version:", "field.appBuild": "Build:", + "field.systemFrameworks": "System-Frameworks:", + "field.systemLibs": "System-Bibliotheken:", + "tooltip.systemFrameworks": "Apple-SDK-Frameworks, durch Kommas getrennt, z. B. Security,CoreBluetooth. Gespeichert in config.make PROJECT_FRAMEWORKS.", + "tooltip.systemLibs": "SDK-Bibliotheken, durch Kommas getrennt, z. B. sqlite3,z für libsqlite3.tbd und libz.tbd. Gespeichert in config.make PROJECT_SYSTEM_LIBS.", "tooltip.appVersionInvalid": "Die Version darf nur Ziffern und Punkte enthalten, z. B. 1, 1.2 oder 1.2.3.", "tooltip.appBuildInvalid": "Der Build muss eine positive ganze Zahl sein, z. B. 42.", "note.appVersionDiffers": "{{file}} hat eine andere Version: {{value}} - die aus config.make wird verwendet.", diff --git a/frontend/locales/en.json b/frontend/locales/en.json index bc0e3891..7667af1a 100644 --- a/frontend/locales/en.json +++ b/frontend/locales/en.json @@ -2,6 +2,7 @@ "nav.create": "create / update", "nav.updateMultiple": "update multiple", "nav.ofMenu": "downloads", + "nav.help": "help", "statusBar.targeting": "Targeting:", "statusBar.noPath": "(no openFrameworks path set)", "field.projectName": "Project name:", @@ -163,6 +164,10 @@ "note.wasm64": "Needs wasm64 libraries: run BITS=64 scripts/emscripten/download_libs.sh (replaces the installed lib/emscripten libraries).", "field.appVersion": "Version:", "field.appBuild": "Build:", + "field.systemFrameworks": "System frameworks:", + "field.systemLibs": "System libraries:", + "tooltip.systemFrameworks": "Apple SDK frameworks, comma-separated, e.g. Security,CoreBluetooth. Saved in config.make PROJECT_FRAMEWORKS.", + "tooltip.systemLibs": "SDK libraries, comma-separated, e.g. sqlite3,z for libsqlite3.tbd and libz.tbd. Saved in config.make PROJECT_SYSTEM_LIBS.", "tooltip.appVersionInvalid": "Version should be digits and dots, e.g. 1, 1.2 or 1.2.3.", "tooltip.appBuildInvalid": "Build should be a positive whole number, e.g. 42.", "note.appVersionDiffers": "{{file}} has a different version: {{value}} - config.make's is used.", diff --git a/frontend/locales/es.json b/frontend/locales/es.json index 876feb23..fbb03ce8 100644 --- a/frontend/locales/es.json +++ b/frontend/locales/es.json @@ -2,6 +2,7 @@ "nav.create": "crear / actualizar", "nav.updateMultiple": "actualizar varios", "nav.ofMenu": "descargas", + "nav.help": "ayuda", "statusBar.targeting": "Destino:", "statusBar.noPath": "(sin ruta de openFrameworks configurada)", "field.projectName": "Nombre del proyecto:", @@ -163,6 +164,10 @@ "note.wasm64": "Requiere bibliotecas wasm64: ejecuta BITS=64 scripts/emscripten/download_libs.sh (reemplaza las bibliotecas lib/emscripten instaladas).", "field.appVersion": "Versión:", "field.appBuild": "Compilación:", + "field.systemFrameworks": "Frameworks del sistema:", + "field.systemLibs": "Bibliotecas del sistema:", + "tooltip.systemFrameworks": "Frameworks del SDK de Apple, separados por comas, p. ej. Security,CoreBluetooth. Se guardan en config.make PROJECT_FRAMEWORKS.", + "tooltip.systemLibs": "Bibliotecas del SDK, separadas por comas, p. ej. sqlite3,z para libsqlite3.tbd y libz.tbd. Se guardan en config.make PROJECT_SYSTEM_LIBS.", "tooltip.appVersionInvalid": "La versión debe contener solo dígitos y puntos, p. ej. 1, 1.2 o 1.2.3.", "tooltip.appBuildInvalid": "La compilación debe ser un número entero positivo, p. ej. 42.", "note.appVersionDiffers": "{{file}} tiene otra versión: {{value}} - se usa la de config.make.", diff --git a/frontend/locales/fr.json b/frontend/locales/fr.json index 0c1b4b80..48ec8d6b 100644 --- a/frontend/locales/fr.json +++ b/frontend/locales/fr.json @@ -2,6 +2,7 @@ "nav.create": "créer / mettre à jour", "nav.updateMultiple": "mise à jour multiple", "nav.ofMenu": "téléchargements", + "nav.help": "aide", "statusBar.targeting": "Cible :", "statusBar.noPath": "(aucun chemin openFrameworks défini)", "field.projectName": "Nom du projet :", @@ -163,6 +164,10 @@ "note.wasm64": "Nécessite les bibliothèques wasm64 : lancez BITS=64 scripts/emscripten/download_libs.sh (remplace les bibliothèques lib/emscripten installées).", "field.appVersion": "Version :", "field.appBuild": "Build :", + "field.systemFrameworks": "Frameworks système :", + "field.systemLibs": "Bibliothèques système :", + "tooltip.systemFrameworks": "Frameworks du SDK Apple, séparés par des virgules, ex. Security,CoreBluetooth. Enregistrés dans config.make PROJECT_FRAMEWORKS.", + "tooltip.systemLibs": "Bibliothèques du SDK, séparées par des virgules, ex. sqlite3,z pour libsqlite3.tbd et libz.tbd. Enregistrées dans config.make PROJECT_SYSTEM_LIBS.", "tooltip.appVersionInvalid": "La version doit contenir uniquement des chiffres et des points, p. ex. 1, 1.2 ou 1.2.3.", "tooltip.appBuildInvalid": "Le build doit être un entier positif, p. ex. 42.", "note.appVersionDiffers": "{{file}} a une autre version : {{value}} - celle de config.make est utilisée.", diff --git a/frontend/locales/ja.json b/frontend/locales/ja.json index 0dc27c1d..782fac14 100644 --- a/frontend/locales/ja.json +++ b/frontend/locales/ja.json @@ -2,6 +2,7 @@ "nav.create": "作成 / 更新", "nav.updateMultiple": "複数を更新", "nav.ofMenu": "ダウンロード", + "nav.help": "ヘルプ", "statusBar.targeting": "対象:", "statusBar.noPath": "(openFrameworksのパスが未設定)", "field.projectName": "プロジェクト名:", @@ -163,6 +164,10 @@ "note.wasm64": "wasm64 ライブラリが必要です: BITS=64 scripts/emscripten/download_libs.sh を実行してください (インストール済みの lib/emscripten ライブラリを置き換えます)。", "field.appVersion": "バージョン:", "field.appBuild": "ビルド:", + "field.systemFrameworks": "システムフレームワーク:", + "field.systemLibs": "システムライブラリ:", + "tooltip.systemFrameworks": "Apple SDK のフレームワーク(カンマ区切り、例: Security,CoreBluetooth)。config.make の PROJECT_FRAMEWORKS に保存されます。", + "tooltip.systemLibs": "SDK のライブラリ(カンマ区切り、例: sqlite3,z で libsqlite3.tbd と libz.tbd)。config.make の PROJECT_SYSTEM_LIBS に保存されます。", "tooltip.appVersionInvalid": "バージョンは数字とドットのみで指定してください (例: 1、1.2、1.2.3)。", "tooltip.appBuildInvalid": "ビルドは正の整数で指定してください (例: 42)。", "note.appVersionDiffers": "{{file}} のバージョンが異なります: {{value}} - config.make の値を使用します。", diff --git a/frontend/locales/ko.json b/frontend/locales/ko.json index 37a6f85e..0db3bdd6 100644 --- a/frontend/locales/ko.json +++ b/frontend/locales/ko.json @@ -2,6 +2,7 @@ "nav.create": "생성 / 업데이트", "nav.updateMultiple": "여러 개 업데이트", "nav.ofMenu": "다운로드", + "nav.help": "도움말", "statusBar.targeting": "대상:", "statusBar.noPath": "(openFrameworks 경로가 설정되지 않음)", "field.projectName": "프로젝트 이름:", @@ -163,6 +164,10 @@ "note.wasm64": "wasm64 라이브러리가 필요합니다: BITS=64 scripts/emscripten/download_libs.sh 를 실행하세요 (설치된 lib/emscripten 라이브러리를 교체합니다).", "field.appVersion": "버전:", "field.appBuild": "빌드:", + "field.systemFrameworks": "시스템 프레임워크:", + "field.systemLibs": "시스템 라이브러리:", + "tooltip.systemFrameworks": "Apple SDK 프레임워크(쉼표로 구분, 예: Security,CoreBluetooth). config.make의 PROJECT_FRAMEWORKS에 저장됩니다.", + "tooltip.systemLibs": "SDK 라이브러리(쉼표로 구분, 예: sqlite3,z = libsqlite3.tbd, libz.tbd). config.make의 PROJECT_SYSTEM_LIBS에 저장됩니다.", "tooltip.appVersionInvalid": "버전은 숫자와 점만 사용할 수 있습니다 (예: 1, 1.2, 1.2.3).", "tooltip.appBuildInvalid": "빌드는 양의 정수여야 합니다 (예: 42).", "note.appVersionDiffers": "{{file}}의 버전이 다릅니다: {{value}} - config.make의 값을 사용합니다.", diff --git a/frontend/locales/pt.json b/frontend/locales/pt.json index ca7a671f..7eaadf54 100644 --- a/frontend/locales/pt.json +++ b/frontend/locales/pt.json @@ -2,6 +2,7 @@ "nav.create": "criar / atualizar", "nav.updateMultiple": "atualizar vários", "nav.ofMenu": "downloads", + "nav.help": "ajuda", "statusBar.targeting": "Destino:", "statusBar.noPath": "(nenhum caminho do openFrameworks definido)", "field.projectName": "Nome do projeto:", @@ -163,6 +164,10 @@ "note.wasm64": "Requer bibliotecas wasm64: execute BITS=64 scripts/emscripten/download_libs.sh (substitui as bibliotecas lib/emscripten instaladas).", "field.appVersion": "Versão:", "field.appBuild": "Build:", + "field.systemFrameworks": "Frameworks do sistema:", + "field.systemLibs": "Bibliotecas do sistema:", + "tooltip.systemFrameworks": "Frameworks do SDK da Apple, separados por vírgulas, ex. Security,CoreBluetooth. Salvos em config.make PROJECT_FRAMEWORKS.", + "tooltip.systemLibs": "Bibliotecas do SDK, separadas por vírgulas, ex. sqlite3,z para libsqlite3.tbd e libz.tbd. Salvas em config.make PROJECT_SYSTEM_LIBS.", "tooltip.appVersionInvalid": "A versão deve conter apenas dígitos e pontos, ex.: 1, 1.2 ou 1.2.3.", "tooltip.appBuildInvalid": "O build deve ser um número inteiro positivo, ex.: 42.", "note.appVersionDiffers": "{{file}} tem outra versão: {{value}} - é usada a do config.make.", diff --git a/frontend/locales/ru.json b/frontend/locales/ru.json index ed2e0130..6091c510 100644 --- a/frontend/locales/ru.json +++ b/frontend/locales/ru.json @@ -2,6 +2,7 @@ "nav.create": "создать / обновить", "nav.updateMultiple": "обновить несколько", "nav.ofMenu": "загрузки", + "nav.help": "справка", "statusBar.targeting": "Цель:", "statusBar.noPath": "(путь к openFrameworks не задан)", "field.projectName": "Имя проекта:", @@ -163,6 +164,10 @@ "note.wasm64": "Нужны библиотеки wasm64: запустите BITS=64 scripts/emscripten/download_libs.sh (заменяет установленные библиотеки lib/emscripten).", "field.appVersion": "Версия:", "field.appBuild": "Сборка:", + "field.systemFrameworks": "Системные фреймворки:", + "field.systemLibs": "Системные библиотеки:", + "tooltip.systemFrameworks": "Фреймворки Apple SDK через запятую, например Security,CoreBluetooth. Сохраняются в config.make PROJECT_FRAMEWORKS.", + "tooltip.systemLibs": "Библиотеки SDK через запятую, например sqlite3,z для libsqlite3.tbd и libz.tbd. Сохраняются в config.make PROJECT_SYSTEM_LIBS.", "tooltip.appVersionInvalid": "Версия должна состоять из цифр и точек, например 1, 1.2 или 1.2.3.", "tooltip.appBuildInvalid": "Номер сборки должен быть целым положительным числом, например 42.", "note.appVersionDiffers": "В {{file}} другая версия: {{value}} - используется значение из config.make.", diff --git a/frontend/locales/zh-CN.json b/frontend/locales/zh-CN.json index 24377bdf..b7ef6461 100644 --- a/frontend/locales/zh-CN.json +++ b/frontend/locales/zh-CN.json @@ -2,6 +2,7 @@ "nav.create": "创建 / 更新", "nav.updateMultiple": "批量更新", "nav.ofMenu": "下载", + "nav.help": "帮助", "statusBar.targeting": "目标:", "statusBar.noPath": "(未设置 openFrameworks 路径)", "field.projectName": "项目名称:", @@ -163,6 +164,10 @@ "note.wasm64": "需要 wasm64 库:运行 BITS=64 scripts/emscripten/download_libs.sh(会替换已安装的 lib/emscripten 库)。", "field.appVersion": "版本:", "field.appBuild": "构建号:", + "field.systemFrameworks": "系统框架:", + "field.systemLibs": "系统库:", + "tooltip.systemFrameworks": "Apple SDK 框架,用逗号分隔,例如 Security,CoreBluetooth。保存在 config.make 的 PROJECT_FRAMEWORKS 中。", + "tooltip.systemLibs": "SDK 库,用逗号分隔,例如 sqlite3,z 对应 libsqlite3.tbd 和 libz.tbd。保存在 config.make 的 PROJECT_SYSTEM_LIBS 中。", "tooltip.appVersionInvalid": "版本只能包含数字和点,例如 1、1.2 或 1.2.3。", "tooltip.appBuildInvalid": "构建号必须是正整数,例如 42。", "note.appVersionDiffers": "{{file}} 中的版本不同: {{value}} - 使用 config.make 中的值。", From 66c2740ab0e58cfb1aea6acdcd698a0a933ac8df Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Sat, 31 Oct 2026 12:58:13 +1100 Subject: [PATCH 2/4] Updated cmdLine from 0.117.0 to 0.118.0 and PG GUI from 0.111.0 to 0.112.0 --- commandLine/src/defines.h | 2 +- frontend/npm-shrinkwrap.json | 4 ++-- frontend/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/commandLine/src/defines.h b/commandLine/src/defines.h index fc7501bd..c19a0a2b 100644 --- a/commandLine/src/defines.h +++ b/commandLine/src/defines.h @@ -1,5 +1,5 @@ #define OFPROJECTGENERATOR_MAJOR_VERSION "0" -#define OFPROJECTGENERATOR_MINOR_VERSION "117" +#define OFPROJECTGENERATOR_MINOR_VERSION "118" #define OFPROJECTGENERATOR_PATCH_VERSION "0" #define PG_VERSION (OFPROJECTGENERATOR_MAJOR_VERSION "." OFPROJECTGENERATOR_MINOR_VERSION "." OFPROJECTGENERATOR_PATCH_VERSION) diff --git a/frontend/npm-shrinkwrap.json b/frontend/npm-shrinkwrap.json index 0af59ac5..87e10a6c 100644 --- a/frontend/npm-shrinkwrap.json +++ b/frontend/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "projectGenerator", - "version": "0.111.0", + "version": "0.112.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "projectGenerator", - "version": "0.111.0", + "version": "0.112.0", "license": "MIT", "dependencies": { "@types/jquery": "^3.5.34", diff --git a/frontend/package.json b/frontend/package.json index 52246725..f212fa0f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "projectGenerator", "productName": "projectGenerator", - "version": "0.111.0", + "version": "0.112.0", "description": "Build electron GUI openFrameworks projectGenerator", "license": "MIT", "main": "index.js", From 725ae25e1366e71647ee0b4357fa6d85bc080f1e Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Sat, 31 Oct 2026 13:08:23 +1100 Subject: [PATCH 3/4] System frameworks / libraries fields in advanced options --- commandLine/readme.md | 2 +- frontend/app.js | 2 +- frontend/index.html | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/commandLine/readme.md b/commandLine/readme.md index e95197a2..d6daf837 100644 --- a/commandLine/readme.md +++ b/commandLine/readme.md @@ -79,7 +79,7 @@ Link SDK frameworks and libraries (sqlite3 = `libsqlite3.tbd`) to a project: and read back on every update, so a plain `./projectGenerator -o"pathToOF" pathToProject` keeps them. The Xcode project gets them in Link Binary With Libraries; the makefiles and CMake read the same lines (`-framework Security` on Apple only, `-lsqlite3` everywhere). Edit `config.make` and update the project, or pass an empty `-f` / `--system-libs=` to remove them. -The GUI shows them as System frameworks / System libraries when an Apple platform is selected (see the help tab). +The GUI shows them as System frameworks / System libraries with Advanced options on and an Apple platform selected (see the help tab). diff --git a/frontend/app.js b/frontend/app.js index 0fc8979c..14e4616a 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -1481,7 +1481,7 @@ function updateRendererFieldVisibility() { // advanced only; hidden fields keep the project's values, so updating still keeps them $('#appVersionField').css('display', defaultSettings.advancedMode ? 'flex' : 'none'); $('#appVersionNote').toggle(!!defaultSettings.advancedMode && $('#appVersionNote').text().length > 0); - $('#systemFrameworksField').css('display', selectedPlatforms.some((p) => ['osx', 'ios', 'macos', 'tvos'].includes(p)) ? 'flex' : 'none'); + $('#systemFrameworksField').css('display', defaultSettings.advancedMode && selectedPlatforms.some((p) => ['osx', 'ios', 'macos', 'tvos'].includes(p)) ? 'flex' : 'none'); const glPlatforms = ['osx', 'vs', 'msys2', 'linux', 'linux64', 'linuxarmv6l', 'linuxarmv7l', 'linuxaarch64', 'vscode']; $('#glField').toggle(!!defaultSettings.advancedMode && selectedPlatforms.some((p) => glPlatforms.includes(p))); diff --git a/frontend/index.html b/frontend/index.html index 5e4a0038..3f5e954c 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -557,7 +557,7 @@

Platforms and templates

The PG targets this computer's platform (on macOS: osx). With Advanced options on in settings, pick one or more platforms (Xcode, Visual Studio, make, VS Code, Android, Emscripten ...) and templates, which add to them, e.g. VS Code on top of osx or vs.

System frameworks and libraries (macOS / iOS / tvOS)

-

When an Apple platform is selected, add SDK frameworks and libraries the project links to, comma-separated:

+

With Advanced options on and an Apple platform selected, add SDK frameworks and libraries the project links to, comma-separated:

  • System frameworks: Security,CoreBluetooth - Security.framework, CoreBluetooth.framework
  • System libraries: sqlite3,z - libsqlite3.tbd, libz.tbd (libsqlite3, libsqlite3.tbd and -lsqlite3 also work)
  • @@ -568,7 +568,7 @@

    System frameworks and libraries (macOS / iOS / tv

    Xcode gets them in Link Binary With Libraries; make and CMake builds read the same lines (-framework Security, -lsqlite3). Clear a field and update to remove them.

    Advanced options

    -

    Turn on Advanced options in settings for: custom defines, renderer (ANGLE / Dawn / GLon12), OpenGL / GLES / WebGL version, app version and build, post-build script, MSYS2 environment, Emscripten wasm32 / wasm64.

    +

    Turn on Advanced options in settings for: system frameworks and libraries, custom defines, renderer (ANGLE / Dawn / GLon12), OpenGL / GLES / WebGL version, app version and build, post-build script, MSYS2 environment, Emscripten wasm32 / wasm64.

    Downloads

    Download or update the prebuilt openFrameworks libraries, or single (modular) libraries, for your OF path.

    From ab6588eda25d9edfb4d664fa159fa74811c62fd0 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Sat, 31 Oct 2026 13:24:32 +1100 Subject: [PATCH 4/4] System frameworks / libraries can be separated by spaces too --- commandLine/src/projects/baseProject.cpp | 12 ++++++++++-- frontend/app.js | 4 ++-- frontend/index.html | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/commandLine/src/projects/baseProject.cpp b/commandLine/src/projects/baseProject.cpp index 18bfe916..d858f8e3 100644 --- a/commandLine/src/projects/baseProject.cpp +++ b/commandLine/src/projects/baseProject.cpp @@ -1102,9 +1102,17 @@ void baseProject::parseConfigMake(){ } void baseProject::setSystemFrameworks(const std::vector & frameworks, bool frameworksPassed, const std::vector & libs, bool libsPassed) { - systemFrameworksOption = frameworks; + // "Security CoreBluetooth" is two, names have no spaces + auto splitSpaces = [](const std::vector & list) { + std::vector out; + for (auto & l : list) { + for (auto & v : ofSplitString(l, " ", true, true)) out.emplace_back(v); + } + return out; + }; + systemFrameworksOption = splitSpaces(frameworks); systemFrameworksPassed = frameworksPassed; - systemLibsOption = libs; + systemLibsOption = splitSpaces(libs); systemLibsPassed = libsPassed; } diff --git a/frontend/app.js b/frontend/app.js index 14e4616a..82af884b 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -1287,8 +1287,8 @@ function generate() { appVersion: $('#appVersion').val().trim(), appBuild: $('#appBuild').val().trim(), // only for Apple targets; hidden = keep the project's config.make values - systemFrameworks: $('#systemFrameworksField').css('display') !== 'none' ? $('#systemFrameworks').val().split(',').map((s) => s.trim()).filter(Boolean) : null, - systemLibs: $('#systemFrameworksField').css('display') !== 'none' ? $('#systemLibs').val().split(',').map((s) => s.trim()).filter(Boolean) : null + systemFrameworks: $('#systemFrameworksField').css('display') !== 'none' ? $('#systemFrameworks').val().split(/[\s,]+/).filter(Boolean) : null, + systemLibs: $('#systemFrameworksField').css('display') !== 'none' ? $('#systemLibs').val().split(/[\s,]+/).filter(Boolean) : null }; // console.log(gen); diff --git a/frontend/index.html b/frontend/index.html index 3f5e954c..f81e35be 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -557,7 +557,7 @@

    Platforms and templates

    The PG targets this computer's platform (on macOS: osx). With Advanced options on in settings, pick one or more platforms (Xcode, Visual Studio, make, VS Code, Android, Emscripten ...) and templates, which add to them, e.g. VS Code on top of osx or vs.

    System frameworks and libraries (macOS / iOS / tvOS)

    -

    With Advanced options on and an Apple platform selected, add SDK frameworks and libraries the project links to, comma-separated:

    +

    With Advanced options on and an Apple platform selected, add SDK frameworks and libraries the project links to, separated by commas or spaces:

    • System frameworks: Security,CoreBluetooth - Security.framework, CoreBluetooth.framework
    • System libraries: sqlite3,z - libsqlite3.tbd, libz.tbd (libsqlite3, libsqlite3.tbd and -lsqlite3 also work)