mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 13:07:02 +00:00
A Cappuccino project has always needed to have a flat file structure to be able to compile from source in the web browser. A new dictionary can be added to the project's Info.plist with the key 'CPFileTranslationDictionary'. It should contain all the path translations in the project to allow the Browser to find out where in the file structure the source files are. Check in the AppKit framework for an example. Also, a include list can be added in the Info.plist for the key 'CPCompileIncludeFileArray'. The file in the list will be included by a '#include' statement for each file that is compiled in this project A last new feature is to add macros in the 'OBJJ_COMPILER_FLAGS' global variable. It is usually declared in the index.html file. It is done with the format '-Dmacroname[=macrodefinition]'. An updated Info.plist file in the AppKit framework will allow the AppKit to compile from the source in the web browser. The following things is needed to get this to work: 1. Replace the AppKit folder in your project's Frameworks folder with a copy of the AppKit folder from the Cappuccino project. 2. Add a copy of the built Aristo2.blend folder to the AppKit's Resource folder. 3. Add "-DPLATFORM_DOM", "-DPLATFORM_BROWSER" and optionally "-DDEBUG" to the global variable 'OBJJ_COMPILER_FLAGS' in the project's index.html file. The app load time will increase (about 3 seconds on a 2018 MacBook Pro) as the AppKit framework is compiled from source. The Foundation framework is not yet tested but it might be working by adding info about the file structure in the Info.plist file.
318 lines
10 KiB
JavaScript
318 lines
10 KiB
JavaScript
|
|
var FILE = require("file");
|
|
var sprintf = require("printf").sprintf;
|
|
var OS = require("os");
|
|
|
|
var window = exports.window = require("browser/window");
|
|
|
|
if (system.engine === "rhino")
|
|
{
|
|
window.__parent__ = null;
|
|
window.__proto__ = global;
|
|
}
|
|
|
|
// setup OBJJ_HOME, OBJJ_INCLUDE_PATHS, etc
|
|
window.OBJJ_HOME = exports.OBJJ_HOME = FILE.resolve(module.path, "..");
|
|
|
|
var frameworksPath = FILE.resolve(window.OBJJ_HOME, "Frameworks/");
|
|
|
|
var OBJJ_INCLUDE_PATHS = global.OBJJ_INCLUDE_PATHS = exports.OBJJ_INCLUDE_PATHS = [frameworksPath];
|
|
|
|
#include "Includes.js"
|
|
|
|
// Find all narwhal packages with Objective-J frameworks.
|
|
exports.objj_frameworks = [];
|
|
exports.objj_debug_frameworks = [];
|
|
|
|
var catalog = require("narwhal/packages").catalog;
|
|
for (var name in catalog)
|
|
{
|
|
if (!catalog.hasOwnProperty(name))
|
|
continue;
|
|
|
|
var info = catalog[name];
|
|
if (!info)
|
|
continue;
|
|
|
|
var frameworks = info["objj-frameworks"];
|
|
if (frameworks) {
|
|
if (!Array.isArray(frameworks))
|
|
frameworks = [String(frameworks)];
|
|
|
|
exports.objj_frameworks.push.apply(exports.objj_frameworks, frameworks.map(function(aFrameworkPath) {
|
|
return FILE.join(info.directory, aFrameworkPath);
|
|
}));
|
|
}
|
|
|
|
var debugFrameworks = info["objj-debug-frameworks"];
|
|
if (debugFrameworks) {
|
|
if (!Array.isArray(debugFrameworks))
|
|
debugFrameworks = [String(debugFrameworks)];
|
|
|
|
exports.objj_debug_frameworks.push.apply(exports.objj_debug_frameworks, debugFrameworks.map(function(aFrameworkPath) {
|
|
return FILE.join(info.directory, aFrameworkPath);
|
|
}));
|
|
}
|
|
}
|
|
|
|
// push to the front of the array lowest priority first.
|
|
OBJJ_INCLUDE_PATHS.unshift.apply(OBJJ_INCLUDE_PATHS, exports.objj_frameworks);
|
|
OBJJ_INCLUDE_PATHS.unshift.apply(OBJJ_INCLUDE_PATHS, exports.objj_debug_frameworks);
|
|
|
|
if (system.env["OBJJ_INCLUDE_PATHS"])
|
|
OBJJ_INCLUDE_PATHS.unshift.apply(OBJJ_INCLUDE_PATHS, system.env["OBJJ_INCLUDE_PATHS"].split(":"));
|
|
|
|
// bring the "window" object into scope.
|
|
// TODO: somehow make window object the top scope?
|
|
with (window)
|
|
{
|
|
// runs the objj repl or file provided in args
|
|
exports.run = function(args)
|
|
{
|
|
var multipleFiles = false;
|
|
|
|
if (args)
|
|
{
|
|
// we expect args to be in the format:
|
|
// 1) "objj" path
|
|
// 2) optional "-I" args
|
|
// 3) real or "virtual" main.j
|
|
// 4) optional program arguments
|
|
|
|
// copy the args since we're going to modify them
|
|
var argv = args.slice(1);
|
|
var outputFormatInXML = false;
|
|
|
|
if (argv[0] === "--version" || argv[0] === "-v")
|
|
{
|
|
print(exports.fullVersionString());
|
|
return;
|
|
}
|
|
|
|
if (argv[0] === "--help" || argv[0] === "-h")
|
|
{
|
|
print("Usage (objj): " + args[0].split("/").pop() + " [options] [--] files...");
|
|
print(" -v, --version print the current version of objj");
|
|
print(" -I, --objj-include-paths include a specific framework paths")
|
|
print(" -h, --help print this help");
|
|
print(" -m, --multifiles launch objj on several files")
|
|
print(" -x, --xml specify the output format in xml.")
|
|
print(" -g, --include-debug-symbols Include debug symbols when compiling.")
|
|
print(" -T, --dont-include-type-signatures Do not include type signatures when compiling.")
|
|
print(" -O2, --inline-msg-send Inline objj_msgSend function when compiling.")
|
|
return;
|
|
}
|
|
|
|
while (argv.length && argv[0].indexOf('-') === 0)
|
|
{
|
|
switch (argv[0])
|
|
{
|
|
case "--objj-include-paths":
|
|
case "-I":
|
|
argv.shift();
|
|
OBJJ_INCLUDE_PATHS.unshift.apply(OBJJ_INCLUDE_PATHS, argv.shift().split(":"));
|
|
break;
|
|
|
|
case "--multifiles":
|
|
case "-m":
|
|
argv.shift();
|
|
multipleFiles = true;
|
|
break
|
|
|
|
case "-x":
|
|
case "--xml":
|
|
argv.shift();
|
|
exports.messageOutputFormatInXML = true;
|
|
outputFormatInXML = true;
|
|
break;
|
|
|
|
case "-g":
|
|
case "--include-debug-symbols":
|
|
argv.shift();
|
|
var flags = ObjectiveJ.StaticResource.currentCompilerFlags();
|
|
flags.includeMethodFunctionNames = true;
|
|
ObjectiveJ.StaticResource.setCurrentCompilerFlags(flags);
|
|
break;
|
|
|
|
case "-T":
|
|
case "--dont-include-type-signatures":
|
|
argv.shift();
|
|
var flags = ObjectiveJ.StaticResource.currentCompilerFlags();
|
|
flags.includeIvarTypeSignatures = true;
|
|
flags.includeMethodArgumentTypeSignatures = true;
|
|
ObjectiveJ.StaticResource.setCurrentCompilerFlags(flags);
|
|
break;
|
|
|
|
case "-O2":
|
|
case "--inline-msg-send":
|
|
argv.shift();
|
|
var flags = ObjectiveJ.StaticResource.currentCompilerFlags();
|
|
flags.inlineMsgSendFunctions = true;
|
|
ObjectiveJ.StaticResource.setCurrentCompilerFlags(flags);
|
|
break;
|
|
|
|
case "-g":
|
|
case "--include-debug-symbols":
|
|
argv.shift();
|
|
var flags = ObjectiveJ.StaticResource.currentCompilerFlags();
|
|
flags.includeMethodFunctionNames = true;
|
|
ObjectiveJ.StaticResource.setCurrentCompilerFlags(flags);
|
|
break;
|
|
|
|
case "-T":
|
|
case "--dont-include-type-signatures":
|
|
argv.shift();
|
|
var flags = ObjectiveJ.StaticResource.currentCompilerFlags();
|
|
flags.includeIvarTypeSignatures = true;
|
|
flags.includeMethodArgumentTypeSignatures = true;
|
|
ObjectiveJ.StaticResource.setCurrentCompilerFlags(flags);
|
|
break;
|
|
|
|
case "-O2":
|
|
case "--inline-msg-send":
|
|
argv.shift();
|
|
var flags = ObjectiveJ.StaticResource.currentCompilerFlags();
|
|
flags.inlineMsgSendFunctions = true;
|
|
ObjectiveJ.StaticResource.setCurrentCompilerFlags(flags);
|
|
break;
|
|
|
|
default:
|
|
print(args[0].split("/").pop() + " illegal option " + argv[0]);
|
|
OS.exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (argv && argv.length > 0)
|
|
{
|
|
var endCommand = false,
|
|
errors = [];
|
|
|
|
while (argv.length > 0)
|
|
{
|
|
var arg0 = argv.shift(),
|
|
mainFilePath = FILE.canonical(arg0);
|
|
|
|
try
|
|
{
|
|
exports.make_narwhal_factory(mainFilePath)(require, { }, module, system, print);
|
|
}
|
|
catch(e)
|
|
{
|
|
errors.push(e);
|
|
}
|
|
|
|
if (typeof main === "function")
|
|
{
|
|
main([arg0].concat(argv));
|
|
endCommand = true;
|
|
}
|
|
|
|
require("browser/timeout").serviceTimeouts();
|
|
|
|
if (!multipleFiles || endCommand)
|
|
break;
|
|
|
|
ObjectiveJ.Executable.resetCachedFileExecutableSearchers();
|
|
ObjectiveJ.StaticResource.resetRootResources();
|
|
ObjectiveJ.FileExecutable.resetFileExecutables();
|
|
objj_resetRegisterClasses();
|
|
}
|
|
|
|
if (errors.length)
|
|
{
|
|
// Make sure we get exit will failiure
|
|
OS.exit(1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
exports.repl();
|
|
}
|
|
}
|
|
|
|
exports.repl = function()
|
|
{
|
|
var READLINE = require("readline");
|
|
|
|
var historyPath = FILE.path(system.env["HOME"], ".objj_history");
|
|
var historyFile = null;
|
|
|
|
if (historyPath.exists() && READLINE.addHistory) {
|
|
historyPath.read({ charset : "UTF-8" }).split("\n").forEach(function(line) {
|
|
if (line.trim())
|
|
READLINE.addHistory(line);
|
|
});
|
|
}
|
|
|
|
try {
|
|
historyFile = historyPath.open("a", { charset : "UTF-8" });
|
|
} catch (e) {
|
|
system.stderr.print("Warning: Can't open history file '"+historyFile+"' for writing.");
|
|
}
|
|
|
|
while (true)
|
|
{
|
|
try {
|
|
system.stdout.write("objj> ").flush();
|
|
|
|
var line = READLINE.readline();
|
|
if (line && historyFile)
|
|
historyFile.write(line).write("\n").flush();
|
|
|
|
var result = exports.objj_eval(line);
|
|
if (result !== undefined)
|
|
print(result);
|
|
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
|
|
require("browser/timeout").serviceTimeouts();
|
|
}
|
|
};
|
|
|
|
// creates a narwhal factory function in the objj module scope
|
|
exports.make_narwhal_factory = function(path, basePath, filenameTranslateDictionary)
|
|
{
|
|
return function(require, exports, module, system, print)
|
|
{
|
|
Executable.setCommonJSParameters("require", "exports", "module", "system", "print", "window");
|
|
Executable.setCommonJSArguments(require, exports, module, system, print, window);
|
|
filenameTranslateDictionary && Executable.setFilenameTranslateDictionary(filenameTranslateDictionary);
|
|
Executable.fileImporterForURL(basePath ? basePath : FILE.dirname(path))(path, YES);
|
|
}
|
|
};
|
|
|
|
} // end "with"
|
|
|
|
var pkg = null;
|
|
function getPackage() {
|
|
if (!pkg)
|
|
pkg = JSON.parse(FILE.path(module.path).dirname().dirname().join("package.json").read({ charset : "UTF-8" }));
|
|
return pkg;
|
|
}
|
|
|
|
exports.version = function() { return getPackage()["version"]; }
|
|
exports.revision = function() { return getPackage()["cappuccino-revision"]; }
|
|
exports.timestamp = function() { return new Date(getPackage()["cappuccino-timestamp"]); }
|
|
|
|
exports.fullVersionString = function() {
|
|
return sprintf("objective-j %s (%04d-%02d-%02d %s)",
|
|
exports.version(),
|
|
exports.timestamp().getUTCFullYear(),
|
|
exports.timestamp().getUTCMonth()+1,
|
|
exports.timestamp().getUTCDate(),
|
|
exports.revision().slice(0,6)
|
|
);
|
|
}
|
|
|
|
global.ObjectiveJ = {};
|
|
|
|
for (var key in exports)
|
|
if (Object.prototype.hasOwnProperty.call(exports, key))
|
|
global.ObjectiveJ[key] = exports[key];
|
|
|
|
if (require.main == module.id)
|
|
exports.run(system.args);
|