Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-23570] Add support for dynamic Frameworks #159

Merged
merged 18 commits into from Sep 18, 2017

Conversation

janvennemann
Copy link
Contributor

@hansemannn hansemannn added this to the v2.2.0 milestone Apr 22, 2017
filePathAndName = filePathAndName.substr(lastSlashBeforeFramework + 1);
} else {
filePathAndName = replace(CXStringToString(clang_getFileName(file)), ctx->getSDKPath(), "");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor formatting issue

}
var frameworkName = frameworkNameMatches[1];
var frameworkHeadersPath = path.join(dynamicFrameworkPath, 'Headers');
var moduleMapPathAndFilename = path.join(dynamicFrameworkPath, 'Modules', 'module.modulemap');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the modulemap always named module ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to disagree. There are module maps like RobotKit.modulemap, AWSCore.modulemap and AWSMobileAnalytics.modulemap available out there which would not be handled correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, can you give a more specific example? I just tried AWSCore from CocoaPods and the built AWSCore.Framework only includes a module.modulemap.

cacheTokenData.specs.push(checksumMatches[1]);
checksumMatches = specChecksumRegex.exec(podLockfileContent);
}
var podfileChecksumMatch = podLockfileContent.match(/PODFILE CHECKSUM: (.*)/);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this working with CocoaPods 0.39 as well? If not we should officially remove it's support as we work more intensively with it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, you are right, a Podfile for <=0.39 will not contain the Podfile checksum. While just testing this i was also running into http://blog.cocoapods.org/Sharding/. Considering this we should definitely drop the support for CocoaPods 0.39. Hyperloop 2.2.0 would be the perfect release for that, hence i created TIMOB-24623 and i'd say we leave this as is.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feeling bad to do it without a major release-bump, but it would irritate people. So I guess we can make an excuse and remove it in 2.2.0. We deprecated it already right? I know we left a note, but it should definitely show a clear deprecating note by now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we print a warning if a version below 1.0 is used here.

var f = includes[fw] || {};
extractImplementations(fn, f);
includes[fw] = f;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obviously no fan of string comparisons, but I'm wondering if there might be a way without it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't know how else to properly determine the framework/library name. The path is always structured something like Headers/<LibraryName>/HeaderName.h. There can be more subfolders under Headers so i guess this is the easiest way.

* @param {Object} data The CocoaPods metabase mappings to store
*/
function writeCocoaPodsMetabaseMappingsToCache(cacheDir, cacheToken, data) {
var cacheFilename = 'metabase-mappings-cocoapods-' + cacheToken + '.json';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to leave a note somewhere that this name is used across the project or reference it from a global config file. Not sure what's the best way to deal with hardcoded values here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That cache file is only accessed inside the metabase.js file so there is no need to make it available globally. Although, for better maintainability i moved this line to a separate function, so the naming can be controlled from a single place.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect, thanks.

@hansemannn
Copy link
Contributor

Different question: We enable dynamic frameworks support for Cocoapods. How about non-cocoapods libraries (e.g. local embedded frameworks)?

@janvennemann
Copy link
Contributor Author

The current implementation is not directly tied to CocoaPods so we can reuse that to support local embedded frameworks in TIMOB-23853 as well.

@hansemannn
Copy link
Contributor

Could we do both together then? Would just love to get the other ticket "In Progress", so the (pretty high number of) watchers are happy that's something is going on.

@janvennemann
Copy link
Contributor Author

Sure we can do that, the Ticket is marked for 2.2.0 anyway. I just already had the CocoaPods stuff laying around from a previous PoC.

@hansemannn
Copy link
Contributor

Yeah sure, 2.1.0 is bundled and out of my head, haha. Great!

@hansemannn
Copy link
Contributor

@janvennemann Can you please resolve the merge conflicts and validate the ticket with the latest changes you did? I would like to schedule a 2.2.0 with this one and #189 asap.

hansemannn and others added 2 commits August 8, 2017 08:25
Support Hyperloop usage of frameworks that are recognized by the new framework hook in the SDK. Also refactors a major party of the CocoaPods dyanamic framework support to support additional third-party framework configurations.
@janvennemann janvennemann changed the title [TIMOB-23570] Add support for dynamic Frameworks from CocoaPods [TIMOB-23570] Add support for dynamic Frameworks Sep 13, 2017
@@ -308,6 +314,33 @@ function generateFromJSON (name, json, state, callback, includes) {
}

/**
* Takes a single metadata object and normalized the framework property on that object.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

normalizes

* This normalization will try to associate the path with a virtual third-party
* framework that is configured in the appc.js file, and replace it with the virtual
* framework name. Should the path be unknown we remove the framework property as
* it is a symbol which can not be associated to a specific framework and we can't
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cannot or can't

@@ -77,8 +77,11 @@ function generate (json, mod, state) {
m.class.obj_class_method.length ||
Object.keys(m.class.static_variables).length ||
m.class.blocks.length) {
if (mod.filename && mod.filename.indexOf('/') > 0) {
m.import = mod.filename;
if (mod.filename.match(/-Swift\.h$/)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do all Swift frameworks expose their Obj-c header with the "-Swift.h" suffix?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Xcode will automatically generate that header filename using the PRODUCT_MODULE_NAME build setting and adds -Swift.

/**
* Creates a MD5 hash from the given string data.
*
* @param {String} data Data the hash will be genreated for
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generated

* and their header file.
*
* Frameworks written in Swift are currently only supported if they provide an
* ObjC Interface Header.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interface header

var implementationToHeaderFileMap = includes[frameworkName] || {};
extractImplementations(headerPathAndFilename, implementationToHeaderFileMap);
includes[frameworkName] = implementationToHeaderFileMap;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are inline functions still a valid procedure in JS? Not really a fan of it.

var objcInterfaceHeaderFilename = objcInterfaceHeaderMatch[1];
var headerPathAndFilename = path.join(frameworkHeadersPath, objcInterfaceHeaderFilename);
if (!fs.existsSync(headerPathAndFilename)) {
return callback(new Error('Objective-C interface header file for swift based framework ' + frameworkName.green + ' not found at expected path ' + headerPathAndFilename.cyan + '.'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'Objective-C interface header-file for Swift-based framework ' frameworkName.green + ' not found at expected path ' + headerPathAndFilename.cyan + '.'

if (!fs.existsSync(headerPathAndFilename)) {
return callback(new Error('Objective-C interface header file for swift based framework ' + frameworkName.green + ' not found at expected path ' + headerPathAndFilename.cyan + '.'));
}
util.logger.trace('Swift based framework detected, parsing Objective-C interface header ' + objcInterfaceHeaderFilename.cyan);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swift-based

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either use header or header-file every time. Above it's header-file, here it's header.

if (frameworkPosition != std::string::npos) {
size_t slashBeforeFrameworkPosition = filename.find_last_of("/", frameworkPosition);
return filename.substr(slashBeforeFrameworkPosition + 1, frameworkPosition - (slashBeforeFrameworkPosition + 1));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation

}
kv["framework"] = getFramework();
kv["thirdparty"] = !getContext()->isSystemLocation(filename);
kv["filename"] = filename;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation

@@ -15,53 +15,61 @@ exports.cliVersion = '>=3.2';
exports.init = init;

/**
* Main entry-point for our plugin which looks for the platform specific
* plugin to invoke
* main entry point for our plugin which looks for the platform specific
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Main

* main entry point for our plugin which looks for the platform specific
* plugin to invoke.
*
* A priority of 1300 to makes sure the Hyperloop plugin starts only after the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1300 makes

Copy link
Contributor

@hansemannn hansemannn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some review comments to be addressed.

Copy link
Contributor

@hansemannn hansemannn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CR looks fine now, approved!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants