The OS setup is absolutely standard (Monterey hardly allows anything else). XcodeCapp appears to have been designed with the intent all xibs are stored in the main bundle’s Resources folder and doesn’t seem to behave well if not. Keeping xib resources separate from their associated code resources is increasingly a problem for managing the app, as it grows. Using folders in the Xcode sidebar as logical groups is one answer to that, but, as you point out, XcodeCapp is ill-behaved wrt Xcode project files (in some circumstances). That can, should, and will be fixed, but this app has also grown beyond the point where a monolithic project structure is appropriate. It is also just a nuissance to keep one or more terminal windows open to watch and compile nibs. And also to create Objective-C matching class definitions. And Xcode doesn’t have an integrated terminal capability.
Packaging as frameworks, in the Frameworks folder, seems the best approach. At the moment, the modules are under active development - for refactoring. I’m also somewhat concerned about managing imports in the frameworks scenario - there are currently cross-dependencies, and it’s not yet obvious how those will be sorted out.
An allied problem is that I insist on far more separation of concerns into individual files than most people probably do, with smaller controllers for many, if not most, individual sub-views. That’s before getting to datasources and delegates. It’s reached the point these really should be packaged directly with their associated xib assets. Some will suggest avoiding xibs altogether - my experience is it’s very difficult to get a visually polished result going that route.
Simpling moving the module bundles into the Frameworks folder has resulted in jake build problems though. It looks to me as though, as frameworks, they need to be kept entirely out of the main app, built separately, and the build artifacts symlinked or copied in. I assume the reason XcodeCapp allows adding multiple projects which are actively watched is to accommodate just such an approach. I was hoping someone might actually have experience with such, but it seems not.
For the moment, staying with the monolithic project structure is workable. A single module is currently being factored out into a separate app, and that can be used as a base to work back upwards in complexity.
One thing I’ve noticed is the monolithic on-disk structure of this app has negatively influenced coupling of the constituent parts - it’s more rigid than need be.
It’s probably time to revisit Nuage’s project structure - it’s of the scale I envisage this app soon reaching and perhaps it offers some guidance.
Info.plist
file. This allows a deep structured project to be compiled in the browser.@mrcarlberg I had come to the same conclusions over the last few years. The best approach available now has been to use Xcode’s sidebar groups to provide useful organization. It works, but one must be careful to not select ‘Group with folder’. I had noticed #2963 when it was posted, but failed to grasp its significance. fwiw, there has long been a Ruby gem to synchronize Xcode’s virtual folder with the on-disk structure: https://github.com/venmo/synx
An analagous automated tool would nicely complement #2963
Anyone able to describe in detail how an app built for release bootstraps itself? I’m in the process of hardening ours, starting with prohibiting everything, then specifically allowing the pathnames required by the app.
Strangely, one of the first URL requests is for main.j, which isn’t a file in the Release build artifacts, despite having a reference in index.html. Having trouble understanding where the request for main.j originates - although I’m guessing it’s a fallback built into the Objective-J runtime file.
Insight welcomed. It will also help in process of defining the offline operation requirements.
Frameworks/Objective-J/Objective-J.js
is read and executed. It will setup the Objective-J runtime../Info.plist
is read and parsed to get stuff like path to main file (usually main.j
), is it prebuilt etc...Frameworks/Foundation.sj
etc.@import
then read each of the imported files.Foundation/CPObject.j
and some other similar classes. The load system now starts execute each source file from the leafs of the recursive tree that is built when loading all the imported files above. If the source files are not pre built the compiler will generate the compiled javascript code from the previously generated AST tree before executing it.main
function. The function is called.In depths
header from the main wiki page :smile: : https://github.com/cappuccino/cappuccino/wiki/BootstrapBuild/AppName.build
is, as you say, used in the build process. It stores all the compiled source files before the common source file is being created. It is not removed after the build process as it is also used the next time you build to only recompile the files that are changed. You can remove it by doing jake clean
or just remove from command line with rm
or from the FInder.
@mrcarlberg Do you know if the Jakefile syntax is sufficiently close to that of a Makefile for a make linter to be usable?
I’ve just had a modification to the standard Jakefile in a project which unintentionally introduced invalid characters. Running jake
produced very unhelpful feedback — it complained the problem was in the Cappuccino’s narwhal bootstrap.js file :-(
Perhaps I hadn’t had my morning coffee, but it took an hour for the eureka moment when I realized the problem was in the Jakefile itself.
gtavares@Gustavos-MacBook-Air Browser % ./gtktest
/Users/gtavares/Developer/cappuccino/node_modules/@objj/runtime/ lib/objective-j.js:3946
throw new Error("Could not load file at " + aURL + (compilingFileUrl ? " when compiling " + compilingFileUrl : "") + "\nwith includeURLs: " + StaticResource.includeURLs());
^
Error: Could not load file at Foundation/Foundation.j when compiling file:/Users/gtavares/Desktop/Browser/gtktest
with includeURLs: /Users/gtavares/Desktop/Browser/Frameworks/,/Users/gtavares/Developer/cappuccino/dist/objective-j/Frameworks/
at completed (/Users/gtavares/Developer/cappuccino/node_modules/@objj/runtime/lib/objective-j.js:3946:31)
/Users/gtavares/Developer/cappuccino/
and my $CAPP_BUILD set to /Users/gtavares/Developer/cappuccino/Build
#!/usr/bin/env objj
gtavares@Gustavos-MacBook-Air Browser % ./gtktest
@implementation CPBundle (IsEqual)
^
ERROR line 62 in file:/Users/gtavares/Desktop/Browser/gtktest:62: Class CPBundle not found
/Users/gtavares/Developer/cappuccino/node_modules/@objj/runtime/lib/objective-j.js:3702
throw "Compilation error";
^
Compilation error
(Use `node --trace-uncaught ...` to show where the exception was thrown)
Node.js v17.0.1
@mucholove Returned here to a project after a month’s absence to find nib2cib
refusing to compile xibs that previously worked. Only changes to the machine are a handful of new commits to Cappuccino (including my fixes for nib2cib
), and the 12.0.1 update to Monterey.
Has your system also moved from macOS 12.0 to 12.0.1 in your downtime interval?
In my case, the problem seems to be permissions problems at the ibtool
phase — despite that command working just fine when run manually in the terminal. Don’t have time just now to sort it out though — reverted to using a trusty High Sierra installation.
includeURLs
are the paths to the current working directory /Users/gtavares/Desktop/Browser/gtktest
and the current installed version of the Objective-J framework /Users/gtavares/Developer/cappuccino/dist/objective-j/Frameworks
. What is missing is the path to the current installed Cappuccino framework /Users/gtavares/Developer/cappuccino/dist/cappuccino/Frameworks
. I think this is a bug in the @objj/runtime
node module. I will look into why this is happening.includeURLs
but could be added manually with the environment variable OBJJ_INCLUDE_PATHS
Property List error: Unexpected character N at line 1 / JSON error: JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0.
imagesize
needs to be replaced in the node version — it is used by nib2cib
if a xib contains images.