mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-10-07 09:28:02 +00:00
Added significantly improved platform support.
Reviewed by me.
This commit is contained in:
1 parent
409fab31e6
commit
b3cc75fe46
13 files changed
+159
-511
No files matched your search
+3
-2
@@ -32,7 +32,8 @@ Specs[:AppKitDebug] = ObjectiveJ::BundleSpecification.new do |s|
|
||||
s.license = ObjectiveJ::License::LGPL_v2_1
|
||||
s.build_path = File.join($BUILD_DIR, 'Debug', 'AppKit')
|
||||
s.intermediates_path = File.join($BUILD_DIR, 'AppKit.build', 'Debug')
|
||||
s.flags = ['PLATFORM_DOM', 'DEBUG']
|
||||
s.flags = ['DEBUG']
|
||||
s.platforms = [ObjectiveJ::Platform::Browser, ObjectiveJ::Platform::Rhino]
|
||||
end
|
||||
|
||||
bundle Specs[:AppKitDebug], :AppKitDebug
|
||||
@@ -50,7 +51,7 @@ Specs[:AppKitRelease] = ObjectiveJ::BundleSpecification.new do |s|
|
||||
s.license = ObjectiveJ::License::LGPL_v2_1
|
||||
s.build_path = File.join($BUILD_DIR, 'Release', 'AppKit')
|
||||
s.intermediates_path = File.join($BUILD_DIR, 'AppKit.build', 'Release')
|
||||
s.flag = 'PLATFORM_DOM'
|
||||
s.platforms = [ObjectiveJ::Platform::Browser, ObjectiveJ::Platform::Rhino]
|
||||
end
|
||||
|
||||
bundle Specs[:AppKitRelease], :AppKitRelease
|
||||
|
||||
@@ -1,253 +0,0 @@
|
||||
|
||||
importPackage(java.lang);
|
||||
|
||||
importClass(java.io.File);
|
||||
importClass(java.io.BufferedReader);
|
||||
importClass(java.io.FileReader);
|
||||
importClass(java.io.BufferedWriter);
|
||||
importClass(java.io.FileWriter);
|
||||
|
||||
|
||||
function main()
|
||||
{
|
||||
var index = 0,
|
||||
count = arguments.length,
|
||||
bundlePath = NULL;
|
||||
|
||||
for (; index < count; ++index)
|
||||
bundlePath = arguments[index];
|
||||
alert(bundlePath)
|
||||
var bundleFile = new File(bundlePath).getCanonicalFile(),
|
||||
bundlePath = String(bundleFile.getCanonicalPath()),
|
||||
inlinedBundle = readBundle(bundleFile, true),
|
||||
inlinedFiles = [],
|
||||
replacedFiles = [],
|
||||
staticContent = "";
|
||||
|
||||
// Find all internal bundles.
|
||||
var bundleCandidates = getFiles(bundleFile, "plist"),
|
||||
bundleCandidatesCount = bundleCandidates.length;
|
||||
|
||||
while (bundleCandidatesCount--)
|
||||
{
|
||||
var bundleCandidate = bundleCandidates[bundleCandidatesCount];
|
||||
|
||||
// We only care about Info.plists, specifically the ones that aren't us.
|
||||
if (String(bundleCandidate.getName()) !== "Info.plist" || String(bundleCandidate.getCanonicalPath()) === inlinedBundle.path)
|
||||
continue;
|
||||
|
||||
var infoDictionary = readPlist(bundleCandidate);
|
||||
|
||||
// At least one of these two has to be present for this to be a real deal bundle.
|
||||
if (!dictionary_getValue(infoDictionary, "CPBundleIdentifier") && !dictionary_getValue(infoDictionary, "CPBundleName"))
|
||||
continue;
|
||||
|
||||
java.lang.System.out.println(" Examining " + pathRelativeTo(bundleCandidate.getCanonicalPath(), bundlePath));
|
||||
|
||||
dictionary_removeValue(infoDictionary, "CPBundleExecutable");
|
||||
|
||||
var bundle = readBundle(bundleCandidate.getParentFile(), true);
|
||||
|
||||
bundle.path = pathRelativeTo(bundle.path, bundlePath);
|
||||
|
||||
// We want to inline the info plist too.
|
||||
var inlinedFiles = [makeOBJJPlistFile(infoDictionary, bundleCandidate, bundle)].concat(bundle.files),
|
||||
index = 0,
|
||||
count = inlinedFiles.length;
|
||||
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
var file = inlinedFiles[index];
|
||||
|
||||
file.path = pathRelativeTo(String(file.path), bundlePath);
|
||||
|
||||
java.lang.System.out.println(" Inlining " + file.path);
|
||||
|
||||
replacedFiles.push(file.path);
|
||||
staticContent += fileToMarkedString(inlinedFiles[index], true);
|
||||
}
|
||||
}
|
||||
|
||||
var index = 0,
|
||||
existingStaticFiles = inlinedBundle.files,
|
||||
count = existingStaticFiles.length,
|
||||
topLevelContent = "@STATIC;1.0;";
|
||||
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
var file = existingStaticFiles[index];
|
||||
|
||||
// If this isn't actually part of our bundle, drop it!
|
||||
if (file.bundle !== inlinedBundle)
|
||||
continue;
|
||||
|
||||
file.path = pathRelativeTo(String(file.path), bundlePath);
|
||||
|
||||
replacedFiles.push(file.path);
|
||||
topLevelContent += fileToMarkedString(file, false);
|
||||
}
|
||||
|
||||
dictionary_setValue(inlinedBundle.info, "CPBundleReplacedFiles", replacedFiles);
|
||||
|
||||
writeContentsToFile(CPPropertyListCreateXMLData(inlinedBundle.info).string, inlinedBundle.path);
|
||||
writeContentsToFile(topLevelContent + staticContent, inlinedBundle._staticContentPath);
|
||||
}
|
||||
|
||||
function fileToMarkedString(anOBJJFile, encodeBundle)
|
||||
{
|
||||
var markedString = "";
|
||||
|
||||
markedString += MARKER_PATH + ';' + anOBJJFile.path.length + ';' + anOBJJFile.path;
|
||||
|
||||
if (encodeBundle)
|
||||
markedString += MARKER_BUNDLE + ';' + anOBJJFile.bundle.path.length + ';' + anOBJJFile.bundle.path;
|
||||
|
||||
var fragments = anOBJJFile.fragments;
|
||||
|
||||
if (fragments && fragments.length > 0)
|
||||
{
|
||||
var fragmentIndex = 0,
|
||||
fragmentCount = fragments.length;
|
||||
|
||||
for (; fragmentIndex < fragmentCount; ++fragmentIndex)
|
||||
markedString += fragments[fragmentIndex].toMarkedString();
|
||||
}
|
||||
|
||||
else
|
||||
markedString += MARKER_TEXT + ';' + anOBJJFile.contents.length + ';' + anOBJJFile.contents;
|
||||
|
||||
return markedString;
|
||||
}
|
||||
|
||||
function makeOBJJPlistFile(aDictionary, aFile, aBundle)
|
||||
{
|
||||
var file = new objj_file();
|
||||
|
||||
file.path = typeof aFile === "string" ? aFile : aFile.getCanonicalPath();
|
||||
file.bundle = aBundle;
|
||||
file.contents = CPPropertyListCreate280NorthData(aDictionary).string;
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
function pathRelativeTo(target, relativeTo)
|
||||
{
|
||||
var components = [],
|
||||
targetParts = target.split("/"),
|
||||
relativeParts = relativeTo ? relativeTo.split("/") : [];
|
||||
|
||||
var i = 0;
|
||||
while (i < targetParts.length)
|
||||
{
|
||||
if (targetParts[i] != relativeParts[i])
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
for (var j = i; j < relativeParts.length; j++)
|
||||
components.push("..");
|
||||
|
||||
for (var j = i; j < targetParts.length; j++)
|
||||
components.push(targetParts[j]);
|
||||
|
||||
var result = components.join("/");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function readPlist(/*File*/ aFile)
|
||||
{
|
||||
var fileContents = readFile(aFile);
|
||||
|
||||
var data = new objj_data();
|
||||
data.string = fileContents;
|
||||
|
||||
return new CPPropertyListCreateFromData(data);
|
||||
}
|
||||
|
||||
function readBundle(/*File*/ aFile, /*Boolean*/ shouldDecompile)
|
||||
{
|
||||
var bundlePath = typeof aFile === "string" ? new File(aFile).getCanonicalPath() : aFile.getCanonicalPath(),
|
||||
infoPath = bundlePath + "/Info.plist";
|
||||
|
||||
//err
|
||||
var bundle = new objj_bundle();
|
||||
|
||||
bundle.path = infoPath;
|
||||
bundle.info = readPlist(infoPath);
|
||||
bundle._staticFilePaths = dictionary_getValue(bundle.info, "CPBundleReplacedFiles");
|
||||
|
||||
if (bundle._staticFilePaths.length)
|
||||
{
|
||||
bundle._staticContentPath = staticContentPath = bundlePath + '/' + dictionary_getValue(bundle.info, "CPBundleExecutable");
|
||||
|
||||
//err
|
||||
|
||||
bundle._staticContent = readFile(staticContentPath);
|
||||
|
||||
if (shouldDecompile)
|
||||
bundle.files = objj_decompile(bundle._staticContent, bundle);
|
||||
}
|
||||
else
|
||||
bundle._staticContent = "";
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
function getFiles(/*File*/ sourceDirectory, /*nil|String|Array<String>*/ extensions, /*Array*/ exclusions)
|
||||
{
|
||||
var matches = [],
|
||||
files = sourceDirectory.listFiles(),
|
||||
hasMultipleExtensions = typeof extensions !== "string";
|
||||
|
||||
if (files)
|
||||
{
|
||||
var index = 0,
|
||||
count = files.length;
|
||||
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
var file = files[index].getCanonicalFile(),
|
||||
name = String(file.getName()),
|
||||
isValidExtension = !extensions;
|
||||
|
||||
if (exclusions && fileArrayContainsFile(exclusions, file))
|
||||
continue;
|
||||
|
||||
if (!isValidExtension)
|
||||
if (hasMultipleExtensions)
|
||||
{
|
||||
var extensionCount = extensions.length;
|
||||
|
||||
while (extensionCount-- && !isValidExtension)
|
||||
{
|
||||
var extension = extensions[extensionCount];
|
||||
|
||||
if (name.substring(name.length - extension.length - 1) === ("." + extension))
|
||||
isValidExtension = true;
|
||||
}
|
||||
}
|
||||
else if (name.substring(name.length - extensions.length - 1) === ("." + extensions))
|
||||
isValidExtension = true;
|
||||
|
||||
if (isValidExtension)
|
||||
matches.push(file);
|
||||
|
||||
if (file.isDirectory())
|
||||
matches = matches.concat(getFiles(file, extensions, exclusions));
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
function writeContentsToFile(/*String*/ contents, /*File*/ aFile)
|
||||
{
|
||||
var writer = new BufferedWriter(new FileWriter(aFile));
|
||||
|
||||
writer.write(contents);
|
||||
|
||||
writer.close();
|
||||
}
|
||||
|
||||
main.apply(main, arguments);
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'rake'
|
||||
require '../../../common'
|
||||
require 'objective-j'
|
||||
|
||||
|
||||
$BUNDLE_SCRIPT = File.join($BUILD_DIR, 'bundle.build', $CONFIGURATION, 'main-concat.js')
|
||||
$BUNDLE_CLASS = File.join($ENVIRONMENT_LIB_DIR, 'bundle', 'main.class')
|
||||
$BUNDLE_EXECUTABLE = File.join($ENVIRONMENT_BIN_DIR, 'bundle')
|
||||
$STANDARD_EXECUTABLE = File.expand_path(File.join('..', 'executable'))
|
||||
|
||||
task :build => [$BUNDLE_CLASS, $BUNDLE_EXECUTABLE]
|
||||
|
||||
Files = [ File.join($HOME_DIR, 'Tools', 'Utilities', 'bridge.js'), #yuck!
|
||||
File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J', 'Rhino.platform', 'Objective-J.js'),
|
||||
'main.js'];
|
||||
|
||||
file_d $BUNDLE_EXECUTABLE => [$STANDARD_EXECUTABLE] do
|
||||
cp($STANDARD_EXECUTABLE, $BUNDLE_EXECUTABLE)
|
||||
File.chmod 0755, $BUNDLE_EXECUTABLE
|
||||
end
|
||||
|
||||
file_d $BUNDLE_SCRIPT => Files do |t|
|
||||
cat(Files, $BUNDLE_SCRIPT)
|
||||
end
|
||||
|
||||
file_d $BUNDLE_CLASS => $BUNDLE_SCRIPT do |t|
|
||||
js2java($BUNDLE_SCRIPT, 'main.class', false)
|
||||
cp(File.join(File.dirname($BUNDLE_SCRIPT), 'main.class'), $BUNDLE_CLASS)
|
||||
end
|
||||
@@ -14,7 +14,7 @@ task :build => [$CPLUTIL_CLASS, $CPLUTIL_EXECUTABLE]
|
||||
|
||||
Files = [ File.join($HOME_DIR, 'Tools', 'Utilities', 'bridge.js'), #yuck!
|
||||
File.join($HOME_DIR, 'Tools', 'Utilities', 'regex-bridge.js'), #double-yuck!
|
||||
File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J', 'Rhino.platform', 'Objective-J.js'),
|
||||
File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J', 'rhino.platform', 'Objective-J.js'),
|
||||
'main.js'];
|
||||
|
||||
file_d $CPLUTIL_EXECUTABLE => [$STANDARD_EXECUTABLE] do
|
||||
|
||||
@@ -13,7 +13,7 @@ $STANDARD_EXECUTABLE = File.expand_path(File.join('..', 'executable'))
|
||||
task :build => [$OBJJ_CLASS, $OBJJ_EXECUTABLE]
|
||||
|
||||
Files = [ File.join($HOME_DIR, 'Tools', 'Utilities', 'bridge.js'), #yuck!
|
||||
File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J', 'Rhino.platform', 'Objective-J.js'),
|
||||
File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J', 'rhino.platform', 'Objective-J.js'),
|
||||
'main.js'];
|
||||
|
||||
file_d $OBJJ_EXECUTABLE => [$STANDARD_EXECUTABLE] do
|
||||
|
||||
@@ -123,7 +123,7 @@ function preprocess(aFilePath, outFilePath, gccArgs, flags)
|
||||
fragments = objj_preprocess(fileContents, { path:"/x" }, {path:filePath}, flags),
|
||||
index = 0,
|
||||
count = fragments.length,
|
||||
preprocessed = MARKER_PATH + ';' + filePath.length + ';' + filePath;
|
||||
preprocessed = "";
|
||||
|
||||
// Writer preprocessed fragments out.
|
||||
for (; index < count; ++index)
|
||||
|
||||
@@ -15,7 +15,7 @@ task :build => [$OBJJC_CLASS, $OBJJC_EXECUTABLE, $OBJJC_JS_COMPILER]
|
||||
|
||||
Files = [ File.join($HOME_DIR, 'Tools', 'Utilities', 'bridge.js'), #yuck!
|
||||
File.join($HOME_DIR, 'Tools', 'Utilities', 'regex-bridge.js'), #double-yuck!
|
||||
File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J', 'Rhino.platform', 'Objective-J.js'),
|
||||
File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J', 'rhino.platform', 'Objective-J.js'),
|
||||
'main.js'];
|
||||
|
||||
file_d $OBJJC_EXECUTABLE => [$STANDARD_EXECUTABLE] do
|
||||
|
||||
@@ -4,7 +4,7 @@ require 'rake'
|
||||
require '../../common'
|
||||
|
||||
|
||||
subprojects = %w{bundle cplutil objj objjc}
|
||||
subprojects = %w{cplutil objj objjc}
|
||||
|
||||
%w(build clean).each do |task_name|
|
||||
task task_name do
|
||||
|
||||
+24
-1
@@ -27,6 +27,7 @@
|
||||
// Look inside bundleResponseCallback.
|
||||
|
||||
|
||||
OBJJ_PLATFORMS = PLATFORMS
|
||||
#define DIRECTORY(aPath) (aPath).substr(0, (aPath).lastIndexOf('/') + 1)
|
||||
|
||||
OBJJFileNotFoundException = "OBJJFileNotFoundException";
|
||||
@@ -364,6 +365,28 @@ objj_search.prototype.didReceiveBundleResponse = function(aResponse)
|
||||
|
||||
if (executablePath)
|
||||
{
|
||||
var platform = NULL,
|
||||
platforms = dictionary_getValue(bundle.info, "CPBundlePlatforms"),
|
||||
index = 0,
|
||||
count = OBJJ_PLATFORMS.length,
|
||||
inner_count = platforms.length;
|
||||
|
||||
// Ugh, no indexOf, no objects-in-common.
|
||||
for(; index < count; ++index)
|
||||
{
|
||||
var innerIndex = 0,
|
||||
currentPlatform = OBJJ_PLATFORMS[index];
|
||||
|
||||
for (; innerIndex < inner_count; ++innerIndex)
|
||||
if(OBJJ_PLATFORMS[index] === platforms[innerIndex])
|
||||
{
|
||||
platform = currentPlatform;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
executablePath = platform + ".platform/" + executablePath;
|
||||
|
||||
this.request(DIRECTORY(aResponse.filePath) + executablePath, this.didReceiveExecutableResponse);
|
||||
|
||||
// FIXME: Is this the right approach?
|
||||
@@ -581,7 +604,7 @@ function objj_decompile(aString, bundle)
|
||||
{
|
||||
case MARKER_PATH: if (file && file.contents && file.path === file.bundle.path)
|
||||
file.bundle.info = CPPropertyListCreateWithData({string:file.contents});
|
||||
|
||||
|
||||
file = new objj_file();
|
||||
file.path = DIRECTORY(bundle.path) + text;
|
||||
file.bundle = bundle;
|
||||
|
||||
@@ -10,7 +10,7 @@ $ENVIRONMENT_PRODUCT = File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J')
|
||||
|
||||
$LICENSE_FILE = File.join($PRODUCT, 'LICENSE')
|
||||
$BROWSER_FILE = File.join($PRODUCT, 'Objective-J.js')
|
||||
$RHINO_FILE = File.join($PRODUCT, 'Rhino.platform', 'Objective-J.js')
|
||||
$RHINO_FILE = File.join($PRODUCT, 'rhino.platform', 'Objective-J.js')
|
||||
|
||||
task :Products => [$BROWSER_FILE, $RHINO_FILE]
|
||||
|
||||
@@ -34,11 +34,11 @@ Files = [ 'LICENSE.txt',
|
||||
'bootstrap.js'];
|
||||
|
||||
file_d $BROWSER_FILE => Files do |t|
|
||||
build_product(t.name)
|
||||
build_product(t.name, platform_flags(ObjectiveJ::Platform::Browser, ObjectiveJ::Platform::ObjJ))
|
||||
end
|
||||
|
||||
file_d $RHINO_FILE => Files do |t|
|
||||
build_product(t.name, 'RHINO')
|
||||
build_product(t.name, platform_flags(ObjectiveJ::Platform::Rhino, ObjectiveJ::Platform::ObjJ))
|
||||
end
|
||||
|
||||
#Framework in environment directory
|
||||
@@ -46,7 +46,11 @@ file_d $ENVIRONMENT_PRODUCT => [:Products] do
|
||||
cp_r($PRODUCT, $ENVIRONMENT_PRODUCT)
|
||||
end
|
||||
|
||||
def build_product(path, *flags)
|
||||
def platform_flags(*platforms)
|
||||
return { 'PLATFORMS' => ('"[' + platforms.uniq.map { |platform| '\"' + platform + '\"' }.join(', ') + ']"') }
|
||||
end
|
||||
|
||||
def build_product(path, flags)
|
||||
|
||||
IO.popen("gcc #{resolve_flags(flags)} -E -x c -P -", "w+") do |preprocessor|
|
||||
|
||||
|
||||
+11
-3
@@ -1,12 +1,18 @@
|
||||
require 'rake'
|
||||
require 'date'
|
||||
require 'plist'
|
||||
|
||||
module ObjectiveJ
|
||||
|
||||
class Platform
|
||||
OBJJ = 'objj'
|
||||
RHINO = 'rhino'
|
||||
BROWSER = 'browser'
|
||||
ObjJ = 'objj'
|
||||
|
||||
Rhino = 'rhino'
|
||||
Desktop = 'desktop'
|
||||
Browser = 'browser'
|
||||
BrowserDesktop = 'browser-desktop'
|
||||
BrowserIPhone = 'browser-iphone'
|
||||
BrowseriPhone = 'browser-iphone'
|
||||
end
|
||||
|
||||
##
|
||||
@@ -197,6 +203,7 @@ module ObjectiveJ
|
||||
attribute :date
|
||||
required_attribute :summary
|
||||
required_attribute :identifier
|
||||
required_attribute :platforms, [Platform::ObjJ]
|
||||
|
||||
read_only :specification_version
|
||||
|
||||
@@ -224,6 +231,7 @@ module ObjectiveJ
|
||||
# attribute_alias_singular :executable, :executables
|
||||
attribute_alias_singular :author, :authors
|
||||
attribute_alias_singular :flag, :flags
|
||||
attribute_alias_singular :platform, :platforms
|
||||
# attribute_alias_singular :require_path, :require_paths
|
||||
# attribute_alias_singular :test_file, :test_files
|
||||
|
||||
|
||||
+108
-78
@@ -1,43 +1,29 @@
|
||||
require 'rake'
|
||||
require 'objective-j/plist'
|
||||
|
||||
|
||||
|
||||
module ObjectiveJ
|
||||
|
||||
# Create a package based upon a Gem spec. Gem packages, as well as
|
||||
# zip files and tar/gzipped packages can be produced by this task.
|
||||
#
|
||||
# In addition to the Rake targets generated by PackageTask, a
|
||||
# GemPackageTask will also generate the following tasks:
|
||||
#
|
||||
# [<b>"<em>package_dir</em>/<em>name</em>-<em>version</em>.gem"</b>]
|
||||
# Create a Ruby GEM package with the given name and version.
|
||||
#
|
||||
# Example using a Ruby GEM spec:
|
||||
#
|
||||
# require 'rubygems'
|
||||
#
|
||||
# spec = Gem::Specification.new do |s|
|
||||
# s.platform = Gem::Platform::RUBY
|
||||
# s.summary = "Ruby based make-like utility."
|
||||
# s.name = 'rake'
|
||||
# s.version = PKG_VERSION
|
||||
# s.requirements << 'none'
|
||||
# s.require_path = 'lib'
|
||||
# s.autorequire = 'rake'
|
||||
# s.files = PKG_FILES
|
||||
# s.description = <<EOF
|
||||
# Rake is a Make-like program implemented in Ruby. Tasks
|
||||
# and dependencies are specified in standard Ruby syntax.
|
||||
# EOF
|
||||
# end
|
||||
#
|
||||
# Rake::GemPackageTask.new(spec) do |pkg|
|
||||
# pkg.need_zip = true
|
||||
# pkg.need_tar = true
|
||||
# end
|
||||
#
|
||||
class BundleTask < Rake::Task
|
||||
|
||||
PLATFORM_DIRECTORIES =
|
||||
{
|
||||
Platform::ObjJ => 'objj.platform',
|
||||
Platform::Rhino => 'rhino.platform',
|
||||
Platform::Browser => 'browser.platform',
|
||||
Platform::BrowserDesktop => 'browser-desktop.platform',
|
||||
Platform::BrowserIPhone => 'browser-iphone.platform'
|
||||
}
|
||||
|
||||
PLATFORM_FLAGS =
|
||||
{
|
||||
Platform::ObjJ => [],
|
||||
Platform::Rhino => ['PLATFORM_RHINO'],
|
||||
Platform::Browser => ['PLATFORM_BROWSER', 'PLATFORM_DOM'],
|
||||
Platform::BrowserDesktop => ['PLATFORM_BROWSER', 'PLATFORM_DOM', 'PLATFORM_DESKTOP'],
|
||||
Platform::BrowserIPhone => ['PLATFORM_BROWSER', 'PLATFORM_DOM', 'PLATFORM_IPHONE', 'PLATFORM_MOBILE']
|
||||
}
|
||||
|
||||
# Objective-J Bundle spec containing the metadata for this bundle.
|
||||
attr_accessor :bundle_spec
|
||||
|
||||
@@ -67,33 +53,48 @@ module ObjectiveJ
|
||||
copied_resources << copied_resource
|
||||
end
|
||||
|
||||
objects_path = @bundle_spec.intermediates_path
|
||||
objects = []
|
||||
replaced_files = []
|
||||
|
||||
# create file tasks for object files
|
||||
@bundle_spec.sources.each do |source|
|
||||
|
||||
object_path = File.join(objects_path, File.basename(source, File.extname(source))) + '.o'
|
||||
flags = []
|
||||
|
||||
@bundle_spec.flags.each do |flag|
|
||||
flags << '-D' + flag
|
||||
info_plist_path = @bundle_spec.build_path + '/Info.plist'
|
||||
info_plist = @bundle_spec.info_plist
|
||||
|
||||
info_plist['CPBundlePlatforms'] = @bundle_spec.platforms;
|
||||
|
||||
file_d info_plist_path do
|
||||
File.open(info_plist_path, 'w') do |file|
|
||||
file.puts info_plist.to_plist
|
||||
end
|
||||
|
||||
file_d object_path => source do
|
||||
IO.popen("objjc #{flags.join(' ')} #{source} -o #{object_path}") do |objjc|
|
||||
puts objjc.read
|
||||
end
|
||||
end
|
||||
|
||||
objects << object_path
|
||||
replaced_files << File.basename(source)
|
||||
end
|
||||
|
||||
#the actual executable path
|
||||
executable_path = File.join(@bundle_spec.build_path, @bundle_spec.name + '.sj')
|
||||
preprocessed_files = []
|
||||
|
||||
# create file tasks for object files
|
||||
@bundle_spec.platforms.uniq.each do |platform|
|
||||
|
||||
executable_path = File.join(@bundle_spec.build_path, PLATFORM_DIRECTORIES[platform], @bundle_spec.name + '.sj')
|
||||
enhance([executable_path])
|
||||
|
||||
file_d executable_path do
|
||||
BundleTask.compact(@bundle_spec.build_path)
|
||||
end
|
||||
|
||||
# Yes its unfortunate that we need to regenerate the whole executable if the Info.plist changes. Oh well.
|
||||
file_d executable_path => info_plist_path
|
||||
|
||||
@bundle_spec.sources.each do |source|
|
||||
|
||||
preprocessed_file = File.join(@bundle_spec.build_path, PLATFORM_DIRECTORIES[platform], File.basename(source))
|
||||
|
||||
file_d preprocessed_file => source do
|
||||
IO.popen("objjc #{resolve_flags(@bundle_spec.flags)} #{resolve_flags(PLATFORM_FLAGS[platform])} #{source} -o #{preprocessed_file}") do |objjc|
|
||||
puts objjc.read
|
||||
end
|
||||
end
|
||||
|
||||
preprocessed_files << preprocessed_file
|
||||
|
||||
file_d executable_path => preprocessed_file
|
||||
end
|
||||
end
|
||||
|
||||
# copy license file
|
||||
license_path = nil
|
||||
|
||||
@@ -108,39 +109,68 @@ module ObjectiveJ
|
||||
else
|
||||
license_path = license
|
||||
end
|
||||
|
||||
file_d executable_path => copied_license
|
||||
|
||||
file_d copied_license => license_path do
|
||||
cp(license_path, copied_license)
|
||||
end
|
||||
end
|
||||
|
||||
enhance(preprocessed_files + copied_resources + [info_plist_path])
|
||||
end
|
||||
|
||||
def BundleTask.compact(path, *patterns)
|
||||
|
||||
puts 'Compacting ' + path
|
||||
|
||||
file executable_path => objects do
|
||||
|
||||
File.open(executable_path, "w") do |file|
|
||||
|
||||
file.write('@STATIC;1.0;')
|
||||
info_plist_path = File.join(path, 'Info.plist')
|
||||
info_plist = Plist::parse_xml(info_plist_path)
|
||||
|
||||
absolute_path = File.expand_path(path) + '/'
|
||||
|
||||
patterns = patterns.map { |pattern| "#{path}/#{pattern}" }
|
||||
|
||||
bundle_name = info_plist['CPBundleName']
|
||||
replaced_files = []
|
||||
|
||||
FileList.new(File.join(path, '**', '*.platform')).each do |platform|
|
||||
|
||||
FileList.new(File.join(platform, '*.j')) do |list|
|
||||
|
||||
objects.each do |object|
|
||||
file.write(IO.read(object))
|
||||
end
|
||||
list.include(*patterns)
|
||||
|
||||
executable_path = File.join(platform, bundle_name) + '.sj'
|
||||
platform_absolute_path = File.expand_path(platform) + '/'
|
||||
|
||||
File.open(executable_path, 'w+') do |executable|
|
||||
|
||||
executable.write '@STATIC;1.0;'
|
||||
|
||||
list.each do |fileName|
|
||||
|
||||
File.open(fileName) do |file|
|
||||
|
||||
if fileName.index(platform_absolute_path) == 0
|
||||
fileName = File.expand_path(fileName)[platform_absolute_path.length..-1]
|
||||
else
|
||||
fileName = File.expand_path(fileName)[absolute_path.length..-1]
|
||||
end
|
||||
|
||||
executable.write "p;#{fileName.length};#{fileName}#{file.read}"
|
||||
|
||||
replaced_files << fileName
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
info_plist_path = @bundle_spec.build_path + '/Info.plist'
|
||||
info_plist = @bundle_spec.info_plist
|
||||
info_plist['CPBundleReplacedFiles'] = replaced_files.uniq
|
||||
info_plist['CPBundleExecutable'] = bundle_name + '.sj'
|
||||
|
||||
info_plist['CPBundleExecutable'] = File.basename(executable_path)
|
||||
info_plist['CPBundleReplacedFiles'] = replaced_files
|
||||
|
||||
file_d info_plist_path do
|
||||
File.open(info_plist_path, 'w') do |file|
|
||||
file.puts info_plist.to_plist
|
||||
end
|
||||
File.open(info_plist_path, 'w') do |file|
|
||||
file.puts info_plist.to_plist
|
||||
end
|
||||
|
||||
enhance(copied_resources + [executable_path, info_plist_path])
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,134 +0,0 @@
|
||||
require 'rake'
|
||||
|
||||
module ObjectiveJ
|
||||
PLIST_START = '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">'
|
||||
PLIST_END = '</plist>'
|
||||
end
|
||||
|
||||
class Module
|
||||
|
||||
def objj_extension(method)
|
||||
|
||||
if instance_methods.include?(method)
|
||||
$stderr.puts "WARNING: Possible conflict with Objective-J extension: #{self}##{method} already exists"
|
||||
else
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Array
|
||||
|
||||
objj_extension('to_plist') do
|
||||
def to_plist(start = true)
|
||||
|
||||
str = '<array>'
|
||||
|
||||
each do |value|
|
||||
str += value.to_plist(false)
|
||||
end
|
||||
|
||||
str = str + '</array>'
|
||||
str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
|
||||
|
||||
return str
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class FalseClass
|
||||
|
||||
objj_extension('to_plist') do
|
||||
def to_plist(start = true)
|
||||
|
||||
str = '<false/>'
|
||||
str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
|
||||
|
||||
return str
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Float
|
||||
|
||||
objj_extension('to_plist') do
|
||||
def to_plist(start = true)
|
||||
|
||||
str = '<real>' + to_s + '</real>'
|
||||
str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
|
||||
|
||||
return str
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Hash
|
||||
|
||||
objj_extension('to_plist') do
|
||||
def to_plist(start = true)
|
||||
|
||||
str = '<dict>'
|
||||
|
||||
each do |key, value|
|
||||
str += '<key>' + key.html_encode + '</key>' + value.to_plist(false)
|
||||
end
|
||||
|
||||
str += '</dict>'
|
||||
str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
|
||||
|
||||
return str
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Integer
|
||||
|
||||
objj_extension('to_plist') do
|
||||
def to_plist(start = true)
|
||||
|
||||
str = '<integer>' + to_s + '</integer>'
|
||||
str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END
|
||||
|
||||
return str
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class String
|
||||
|
||||
objj_extension('to_plist') do
|
||||
def to_plist(start = true)
|
||||
|
||||
str = '<string>' + html_encode + '</string>'
|
||||
str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
|
||||
|
||||
return str
|
||||
end
|
||||
end
|
||||
|
||||
objj_extension('html_encode') do
|
||||
def html_encode
|
||||
return self.gsub(/</, '<').
|
||||
gsub(/>/, '>').
|
||||
gsub(/"/,'"').
|
||||
gsub(/'/, ''').
|
||||
gsub(/&/, '&')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class TrueClass
|
||||
|
||||
objj_extension('to_plist') do
|
||||
def to_plist(start = true)
|
||||
|
||||
str = '<true/>'
|
||||
str = ObjectiveJ::PLIST_START + str + ObjectiveJ::PLIST_END if start
|
||||
|
||||
return str
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user