Skip to content

Commit 8294756

Browse files
authored
Xcode / iOS Fixes v87 (#606)
* cleanname resolutions * Test osx command line fixes * Xcode fixes for copy/add for known and used types. (.modulemap. .bundle, .tdb, .swift, .plist) Swift added set flagged with c++ swift interop 5.9 (C++ can be used) Added auto compile flags for non-arc terms (search for non-arc commands in .mm.cpp.m) Added auto objective-c++ flag for .cpp if obj-c commands Added function for checking file for objc++ VS fixed up exclusions for Apple types for projects / cross xcode kept default type for addSrc flag to disable add phases - test * platform adds for other apple
1 parent 6747851 commit 8294756

File tree

9 files changed

+169
-81
lines changed

9 files changed

+169
-81
lines changed

commandLine/src/addons/ofAddon.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,9 @@ bool ofAddon::load(string addonName, const fs::path& projectDir, const string& t
885885
// we want to set addonMakeName before cleaning the addon name, so it is preserved in the exact same way as it was passed, and the addons.make file can be (re)constructed properly
886886
this->addonMakeName = addonName;
887887

888-
// addonName = cleanName(addonName);
888+
if(parseCleanName){
889+
addonName = cleanName(addonName);
890+
}
889891

890892
if(addonName.empty()){
891893
ofLogError("baseProject::addAddon") << "cant add addon with empty name";

commandLine/src/main.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ enum optionIndex { UNKNOWN,
2828
GET_HOST_PLATFORM,
2929
COMMAND,
3030
BACKUP_PROJECT_FILES,
31-
FRAMEWORKS
31+
FRAMEWORKS,
32+
CLEANNAME_DISABLE
3233
};
3334

3435
constexpr option::Descriptor usage[] = {
@@ -50,6 +51,8 @@ constexpr option::Descriptor usage[] = {
5051
{ BACKUP_PROJECT_FILES, 0, "b", "backup", option::Arg::None, " --backup, -b \tbackup project files when replacing with template" },
5152

5253
{ FRAMEWORKS, 0, "f", "frameworks", option::Arg::Optional, " --frameworks, -f \tframeworks list (such as Vision,ARKit)" },
54+
55+
{ CLEANNAME_DISABLE, 0, "n", "cleanname", option::Arg::Optional, " --cleanname, -f \tcleanname" },
5356

5457
{ 0, 0, 0, 0, 0, 0 }
5558
};
@@ -90,6 +93,7 @@ bool bHelpRequested; // did we request help?
9093
bool bListTemplates; // did we request help?
9194
bool bDryRun; // do dry run (useful for debugging recursive update)
9295
bool bBackup;
96+
bool bCleanName = true;
9397

9498
void consoleSpace() {
9599
std::cout << std::endl;
@@ -462,6 +466,11 @@ int main(int argc, char ** argv) {
462466
if (options[DRYRUN].count() > 0) {
463467
bDryRun = true;
464468
}
469+
470+
if (options[CLEANNAME_DISABLE].count() > 0) {
471+
bCleanName = false;
472+
}
473+
parseCleanName = bCleanName;
465474

466475
if (options[VERSION].count() > 0) {
467476
printVersion();

commandLine/src/projects/baseProject.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,12 @@ void baseProject::addAddon(const std::string & _addonName){
310310
ofLogVerbose("baseProject::addAddon") << _addonName;
311311
// alert( "baseProject::addAddon " + _addonName );
312312

313-
// auto addonName = ofAddon::cleanName(_addonName);
314-
auto addonName = _addonName;
315-
313+
std::string addonName;
314+
if(parseCleanName){
315+
addonName = ofAddon::cleanName(_addonName);
316+
} else {
317+
addonName = _addonName;
318+
}
316319

317320
// FIXME : not target, yes platform.
318321
//#ifdef TARGET_WIN32

commandLine/src/projects/visualStudioProject.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,27 @@ void visualStudioProject::addSrc(const fs::path & srcFile, const fs::path & fold
260260
nodeAdded.append_attribute("Include").set_value(srcFile.c_str());
261261
nodeAdded.append_child("Filter").append_child(pugi::node_pcdata).set_value(folder.c_str());*/
262262

263-
} else if (ext == ".storyboard" || ext == ".mm" || ext == ".m" || ext == ".swift" || ext == ".java" || ext == ".kotlin") {
263+
} else if (ext == ".java" || ext == ".kotlin") {
264264
// Do not add files for other platforms
265+
} else if (
266+
ext == ".storyboard" || // Xcode Interface Builder files
267+
ext == ".xib" || // Xcode Interface Builder files
268+
ext == ".xcassets" || // Xcode Asset catalogs
269+
ext == ".xcconfig" || // Xcode build configuration files
270+
ext == ".entitlements" || // Code signing entitlements (Apple-specific)
271+
ext == ".plist" || // Property List files (Info.plist, macOS/iOS config)
272+
ext == ".mm" || // Objective-C++
273+
ext == ".m" || // Objective-C
274+
ext == ".swift" || // Swift language files
275+
ext == ".modulemap" || // Clang module definition (Xcode/Clang-specific)
276+
ext == ".metal" || // Metal Shading Language (Apple GPU API)
277+
ext == ".tbd" || // Text-based dynamic libraries (Apple SDKs)
278+
ext == ".dylib" || // Dynamic libraries (macOS/iOS equivalent of .dll)
279+
ext == ".framework" ||
280+
ext == ".bundle" ||
281+
ext == ".app" ||
282+
ext == ".xcworkspace" ||
283+
ext == ".xcodeproj") {
265284
} else{
266285
appendValue(doc, "ClCompile", "Include", srcFileString);
267286

commandLine/src/projects/xcodeProject.cpp

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ bool xcodeProject::createProjectFile(){
100100
for (auto & f : {"openFrameworks-Info.plist", "of.entitlements"}) {
101101
copyTemplateFiles.push_back({normalizePath(templatePath / f), normalizePath(projectDir / f)});
102102
}
103-
} else if (target == "ios" || target == "macos") {
103+
} else if (target == "ios" || target == "tvos" || target == "visionos" || target == "catos" || target == "macos") {
104104
for (auto & f : {"ofxiOS-Info.plist", "ofxiOS_Prefix.pch"}) {
105105
copyTemplateFiles.push_back({normalizePath(templatePath / f), normalizePath(projectDir / f)});
106106
try {
@@ -420,11 +420,7 @@ void xcodeProject::addSrc(const fs::path & srcFile, const fs::path & folder, Src
420420
fp.addToBuildPhase = true;
421421
fp.isSrc = true;
422422

423-
// if( type == DEFAULT ){
424-
if( target == "ios" ){
425-
fp.addToBuildPhase = true;
426-
fp.addToResources = true;
427-
}
423+
if( type == DEFAULT ){
428424

429425
if (ext == ".h" || ext == ".hpp"){
430426
fp.addToBuildPhase = false;
@@ -450,44 +446,93 @@ void xcodeProject::addSrc(const fs::path & srcFile, const fs::path & folder, Src
450446
fp.addToBuildPhase = false;
451447
fp.copyBundleResources = true;
452448
}
449+
else if( ext == ".plist" ){
450+
fp.addToBuildPhase = true;
451+
fp.copyBundleResources = true;
452+
}
453+
else if (ext == ".swift"){
454+
fp.addToBuildPhase = true;
455+
for (auto &c : buildConfigs) {
456+
addCommand("Add :objects:" + c + ":buildSettings:OTHER_SWIFT_FLAGS: string -cxx-interoperability-mode=swift-5.9");
457+
// mark all Swift files as C++ interop available :)
458+
}
459+
}
460+
else if (ext == ".xcassets"){
461+
fp.addToBuildResource = true;
462+
fp.addToResources = true;
463+
}
464+
else if (ext == ".modulemap") {
465+
fp.addToBuildPhase = false;
466+
}
467+
else if (ext == ".bundle") {
468+
fp.addToBuildResource = true;
469+
fp.addToResources = true;
470+
}
471+
else if (ext == ".tbd") {
472+
fp.linkBinaryWithLibraries = true;
473+
}
453474

454475

455-
// }
456-
457-
476+
}
458477
string UUID {
459478
addFile(srcFile, folder, fp)
460479
};
461480

462481
if (ext == ".mm" || ext == ".m") {
463482
addCompileFlagsForMMFile(srcFile);
483+
} else if (ext == ".cpp") {
484+
if (containsObjectiveCPlusPlus(srcFile)) {
485+
addCompileFlagsForMMFile(srcFile);
486+
}
464487
}
465488
}
466489

467490
void xcodeProject::addCompileFlagsForMMFile(const fs::path & srcFile) {
468491

469-
// This requires a moro thorough inspection on how to deal with these files, and determine if these need the -fno-objc-arc flag.
470-
// This flag should be added on a file by file basis, rather than the way it is done below where these are added globally, as such messes up other things.
492+
std::ifstream file(srcFile);
493+
if (!file.is_open()) return;
471494

472-
// std::ifstream file(srcFile);
473-
// std::string line;
474-
// bool containsARCFunctions = false;
475-
//#if __APPLE__
476-
// std::regex arcRegex(R"(\b(alloc|dealloc)\b)");
477-
//
478-
// while (std::getline(file, line)) {
479-
// if (std::regex_search(line, arcRegex)) {
480-
// containsARCFunctions = true;
481-
// break;
482-
// }
483-
// }
484-
//#endif
485-
// if (containsARCFunctions) {
486-
// for (auto & c : buildConfigs) {
487-
// addCommand("Add :objects:"+c+":buildSettings:OTHER_CPLUSPLUSFLAGS: string -fno-objc-arc");
488-
// }
489-
// }
495+
bool requiresNoARC = false;
496+
497+
// Named regex for detecting ARC-related function calls in Objective-C++
498+
const std::regex arcFunctionRegex(R"(\b(alloc|dealloc|retain|release|autorelease)\b)");
499+
500+
for (std::string line; std::getline(file, line); ) {
501+
if (std::regex_search(line, arcFunctionRegex)) {
502+
requiresNoARC = true;
503+
break;
504+
}
505+
}
506+
507+
// Tag file as Objective-C++ in Xcode build settings
508+
for (auto & c : buildConfigs) {
509+
addCommand("Add :objects:" + c + ":buildSettings:OTHER_CPLUSPLUSFLAGS: string -x objective-c++");
510+
511+
if (requiresNoARC) {
512+
addCommand("Add :objects:" + c + ":buildSettings:OTHER_CPLUSPLUSFLAGS: string -fno-objc-arc");
513+
}
514+
}
515+
516+
}
517+
518+
bool xcodeProject::containsObjectiveCPlusPlus(const fs::path &filePath) {
519+
std::ifstream file(filePath);
520+
if (!file.is_open()) return false;
490521

522+
// Objective-C++ specific keywords to check -- this will fix the really hard to debug objc++ linking obiguous
523+
std::vector<std::string> objcKeywords = {
524+
"#import", "@interface", "@implementation", "@property",
525+
"@synthesize", "@end"
526+
};
527+
528+
for (std::string line; std::getline(file, line); ) {
529+
for (const auto &keyword : objcKeywords) {
530+
if (line.find(keyword) != std::string::npos) {
531+
return true;
532+
}
533+
}
534+
}
535+
return false;
491536
}
492537

493538

commandLine/src/projects/xcodeProject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
#include "baseProject.h"
44
//#include <unordered_map>
55
#include <map>
6+
#include <fstream>
7+
#include <string>
8+
#include <vector>
9+
#include <regex>
610
using std::string;
711

812
class xcodeProject : public baseProject {
@@ -53,6 +57,8 @@ class xcodeProject : public baseProject {
5357
void addFramework(const fs::path & path, const fs::path & folder, bool isRelativeToSDK = false) override;
5458
void addXCFramework(const fs::path & path, const fs::path & folder);
5559
void addDylib(const fs::path & path, const fs::path & folder);
60+
61+
bool containsObjectiveCPlusPlus(const fs::path &filePath);
5662

5763
void saveScheme();
5864
void renameProject();

commandLine/src/utils/Utils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ unique_ptr<baseProject> getTargetProject(const string & targ) {
435435
// cout << "getTargetProject :" << getTargetString(targ) << endl;
436436
// typedef xcodeProject pgProject;
437437

438-
if (targ == "osx" || targ == "ios" || targ == "macos") {
438+
if (targ == "osx" || targ == "ios" || targ == "macos" || targ == "tvos" || targ == "catos" || targ == "visionos" || targ == "watchos") {
439439
return unique_ptr<xcodeProject>(new xcodeProject(targ));
440440
} else if (targ == "msys2") {
441441
// return unique_ptr<QtCreatorProject>(new QtCreatorProject(targ));

commandLine/src/utils/Utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ using std::cout;
2626
using std::endl;
2727

2828
static bool backupProjectFiles = false;
29+
static bool parseCleanName = true;
2930

3031
static std::map <ofTargetPlatform, std::string> platformsToString {
3132
{ OF_TARGET_ANDROID, "android" },
@@ -54,6 +55,7 @@ static std::vector < std::string > platformsOptions {
5455
"msys2",
5556
"osx",
5657
"vs",
58+
"tvos",
5759
};
5860

5961
string generateUUID(const string & input);

scripts/osx/test_cmdline.sh

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -28,57 +28,59 @@ else
2828
echo "Application is already code-signed and valid"
2929
fi
3030

31-
echo "Test auto path:"
31+
echo "Test: projectGenerator building"
32+
echo "Test 1: test examples templates - auto path to openFrameworks core"
3233
./projectGenerator --recursive -posx ../../examples/templates
34+
echo "Test 1: test examples templates - success"
3335

36+
echo "Test: projectGenerator building"
37+
echo "Test 2: all examples - defined core openFrameworks path ../../"
38+
./projectGenerator --recursive -posx -o../../ ../../examples/ ./projectGenerator
39+
echo "Test 2: all examples - success"
3440

35-
echo "Test all"
36-
./projectGenerator --recursive -posx -o../../ ../../examples/ ./projectGenerator
41+
# echo "test out of folder -o [vs]";
42+
# rm -rf ../../../../../pg2
43+
# mkdir -p ../../../../../pg2
44+
# if ! command -v rsync &> /dev/null
45+
# then
46+
# cp -a ./projectGenerator ../../../../../pg2
47+
# else
48+
# rsync -azp ./projectGenerator ../../../../../pg2
49+
# fi
50+
# cd ../../../../../pg2
51+
# ls -a
52+
# pwd
53+
# ./projectGenerator --recursive -posx -o"./../openFrameworks" ./../openFrameworks/examples/
54+
# errorcode=$?
55+
# if [[ $errorcode -ne 0 ]]; then
56+
# exit $errorcode
57+
# fi
3758

59+
# ./projectGenerator --recursive -posx -o"./../openFrameworks" ./../openFrameworks/examples/
60+
# errorcode=$?
61+
# if [[ $errorcode -ne 0 ]]; then
62+
# exit $errorcode
63+
# fi
3864

39-
echo "test out of folder -o [vs]";
40-
rm -rf ../../../../../pg2
41-
mkdir -p ../../../../../pg2
42-
if ! command -v rsync &> /dev/null
43-
then
44-
cp -a ./projectGenerator ../../../../../pg2
45-
else
46-
rsync -azp ./projectGenerator ../../../../../pg2
47-
fi
48-
cd ../../../../../pg2
49-
ls -a
50-
pwd
51-
./projectGenerator --recursive -posx -o"./../openFrameworks" ./../openFrameworks/examples/
52-
errorcode=$?
53-
if [[ $errorcode -ne 0 ]]; then
54-
exit $errorcode
55-
fi
56-
57-
./projectGenerator --recursive -posx -o"./../openFrameworks" ./../openFrameworks/examples/
58-
errorcode=$?
59-
if [[ $errorcode -ne 0 ]]; then
60-
exit $errorcode
61-
fi
65+
# echo "Test generate new just name"
66+
# ./projectGenerator -o"../openFrameworks" -p"osx" "testingGenerate"
67+
# errorcode=$?
68+
# if [[ $errorcode -ne 0 ]]; then
69+
# exit $errorcode
70+
# fi
71+
# echo "Test generate new / update full path"
72+
# ./projectGenerator -o"../openFrameworks" -p"osx" "../openFrameworks/apps/myApps/testingGenerate"
73+
# errorcode=$?
74+
# if [[ $errorcode -ne 0 ]]; then
75+
# exit $errorcode
76+
# fi
6277

63-
echo "Test generate new just name"
64-
./projectGenerator -o"../openFrameworks" -p"osx" "testingGenerate"
65-
errorcode=$?
66-
if [[ $errorcode -ne 0 ]]; then
67-
exit $errorcode
68-
fi
69-
echo "Test generate new / update full path"
70-
./projectGenerator -o"../openFrameworks" -p"osx" "../openFrameworks/apps/myApps/testingGenerate"
71-
errorcode=$?
72-
if [[ $errorcode -ne 0 ]]; then
73-
exit $errorcode
74-
fi
75-
76-
echo "Test generate full path"
77-
./projectGenerator -o"../openFrameworks" -p"osx" "openFrameworks/apps/myApps/testingGenerate2"
78-
errorcode=$?
79-
if [[ $errorcode -ne 0 ]]; then
80-
exit $errorcode
81-
fi
78+
# echo "Test generate full path"
79+
# ./projectGenerator -o"../openFrameworks" -p"osx" "openFrameworks/apps/myApps/testingGenerate2"
80+
# errorcode=$?
81+
# if [[ $errorcode -ne 0 ]]; then
82+
# exit $errorcode
83+
# fi
8284

8385

8486
echo "Successful projectGenerator tests for [osx]";

0 commit comments

Comments
 (0)