Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.

Add -fvisibility=hidden to macOS dynamic framework and export required symbols#7326

Closed
kkaefer wants to merge 2 commits into
masterfrom
macos-sdk-symbol-visibility
Closed

Add -fvisibility=hidden to macOS dynamic framework and export required symbols#7326
kkaefer wants to merge 2 commits into
masterfrom
macos-sdk-symbol-visibility

Conversation

@kkaefer
Copy link
Copy Markdown
Member

@kkaefer kkaefer commented Dec 7, 2016

Fix for #7281

@kkaefer kkaefer force-pushed the macos-sdk-symbol-visibility branch from ad42e10 to 68d0843 Compare December 8, 2016 10:29
@kkaefer kkaefer requested review from 1ec5 and incanus December 8, 2016 10:29
Copy link
Copy Markdown
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

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

In addition to the comments below, the contributor documentation needs to be updated to note that MGLTypes.h needs to be imported and MGL_EXTERN needs to be used on all new public symbols:

Comment thread platform/macos/src/MGLMapView.h Outdated
ensuring that your use adheres to the relevant terms of use.
*/
IB_DESIGNABLE
MGL_EXTERN
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does Interface Builder still recognize MGLMapView as a designable? IB’s Objective-C scanner unfortunately doesn’t know anything about macros.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

How do I find out whether IB does that? I'm not familiar with it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Open MapDocument.xib. Xcode will automatically start building. After awhile, this:

blank

will turn into this:

designable

It’s a bit underwhelming on macOS, but the iOS SDK version of this displays some important setup instructions, so we should make sure designables in general still work.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I tried this, but couldn't get to a conclusive answer since Xcode's rebuilding is very erratic and it doesn't seem to detect changed files. From what I could tell, it worked both in the MGL_EXTERN IB_DESIGNABLE order and the other way around. I changed the order though so that IB_DESIGNABLE now is directly before @interface.

Comment thread platform/darwin/src/MGLAccountManager.h Outdated
The MGLAccountManager object provides a global way to set a Mapbox API access
token.
*/
MGL_EXTERN
Copy link
Copy Markdown
Contributor

@1ec5 1ec5 Dec 8, 2016

Choose a reason for hiding this comment

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

If I’m not mistaken, placing this macro on a separate line between the comment block and the signature breaks Quick Help, which only looks one line up to find a comment block. Would this macro work if we stick it above the comment block, or better yet on the same line as @interface? We should also make sure jazzy – which like Quick Help also relies on Clang to parse out comment blocks – is OK with whatever we end up with.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

What is Quick Help? How do I invoke Quick Help?

Copy link
Copy Markdown
Contributor

@frederoni frederoni Dec 8, 2016

Choose a reason for hiding this comment

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

+ click on class, property or method.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@frederoni I cannot confirm that behavior; it works for me with the macro as well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nvm @kkaefer I was using an invalid macro. 👍

@param latitude The latitude of the point at the center of the viewport.
@param size The size of the viewport.
@return An altitude measured in meters. */
MGL_EXTERN
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we really need to extern symbols in headers with private or project visibility? What about symbols declared in .m files, then?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Theoretically we shouldn't, since it should be all internal to the binary we're building, however the test target also includes this private header, and linking the lib to the test fails without exporting this symbol. Another way would be to not export this, and change the test so that it doesn't require this symbol, or to move this symbol to the public header.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah, OK, so we need this on anything with Private visibility but not Project visibility (using Xcode terminology here).

@kkaefer kkaefer force-pushed the macos-sdk-symbol-visibility branch from 68d0843 to 2f6c3e1 Compare December 12, 2016 13:53
Comment thread platform/macos/DEVELOPING.md Outdated

1. Ensure that the symbol is pure Objective-C and does not rely on any language features specific to Objective-C++ or the C11 dialect of C – so no namespaced types or classes named with emoji! 🙃 Most projects that depend on this SDK are either written in pure Objective-C (GNU99 dialect) or Swift, which cannot yet bridge C++ types.
1. Name the symbol according to [Cocoa naming conventions](https://developer.apple.com/library/prerelease/content/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html#//apple_ref/doc/uid/10000146i). Use the `MGL` class prefix to avoid conflicts with client code. If the symbol has an analogue in MapKit, name the symbol according to MapKit.
1. Add the macro `MGL_EXTERN` prior to the declaration. To get this macro, include `MGLTypes.h`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

My mistake, this belongs in the next section (which could mention standalone functions as well). This section is for adding anything to a public header, including a property or method.

@kkaefer kkaefer force-pushed the macos-sdk-symbol-visibility branch from 7fed07e to 76925d2 Compare December 12, 2016 17:16
@kkaefer kkaefer requested a review from 1ec5 December 13, 2016 10:12
Comment thread platform/macos/src/MGLMapView.h Outdated
@note You are responsible for getting permission to use the map data and for
ensuring that your use adheres to the relevant terms of use.
*/
MGL_EXTERN
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Putting MGL_EXTERN keyword on a separate line before the IB_DESIGNABLE keyword seems to break Quick Help and the index in general in Xcode 8.2. If you ⌥-click a member of a class or open the code completion popup, you get the documentation about the class itself rather than the member. If you ⌘-click to jump to the definition of a member, you get the line above it instead.

release-ios-v3.4.0 on this line:
release-quick-help

release-code-completion

macos-sdk-symbol-visibility on the same line:
pr-quick-help

pr-code-completion

Putting the two keywords on the same line seems to fix the problem, but I’ve only tried this so far inside macos.xcodeproj so far.

@1ec5 1ec5 added build macOS Mapbox Maps SDK for macOS labels Dec 14, 2016
@kkaefer kkaefer force-pushed the macos-sdk-symbol-visibility branch from 76925d2 to ba873e0 Compare December 14, 2016 16:07
@kkaefer kkaefer requested review from 1ec5 and removed request for incanus December 14, 2016 16:07
@1ec5
Copy link
Copy Markdown
Contributor

1ec5 commented Dec 14, 2016

I'm concerned that we're going to forget to add MGL_EXTERN to a new public class at some point and we won't catch it before a developer notices that their project won't link. Ideally, we'd have tests that cover every class, but we generally don't have tests for UI classes yet. Also, we'd still have to be vigilant about new classes getting pro forma tests. Very often we forget to add a new helper class to the jazzy table of contents, even though we know to look for that change. (Sometimes a PR adds a significant class with some helper classes.)

@frederoni
Copy link
Copy Markdown
Contributor

frederoni commented Dec 14, 2016

Ideally, we'd have tests that cover every class, but we generally don't have tests for UI classes yet.

If we would have tests that would cover every MGL class, the test scheme would link and we wouldn't be able to catch incorrect symbol visibility in time? If that's not the case, it would be fairly easy to use the Objective-C runtime to get a list of all loaded classes and validate visibility on them in a unit test.

@1ec5
Copy link
Copy Markdown
Contributor

1ec5 commented Dec 15, 2016

If we would have tests that would cover every MGL class, the test scheme would link and we wouldn't be able to catch incorrect symbol visibility in time?

I'm not worried about classes we already have. I'm worried about a PR that adds a few public classes, one of which is significant enough that the contributor remembers to make it visible, while they overlook the fact that the other helper classes are also public (or have Private target membership!) and need to be visible. If we're vigilant enough to remind the contributor to add a pro forma "test", we'd already be vigilant enough to remind them to add the macro in the first place. But I estimate that we'd miss a class until after a prerelease about 30% of the time without an automated system. The only way "test everything" would work is if we gather code coverage and already had 100% code coverage, so that every dip in coverage would be detectable.

If that's not the case, it would be fairly easy to use the Objective-C runtime to get a list of all loaded classes and validate visibility on them in a unit test.

This PR is about linker visibility, not runtime visibility. How would we distinguish between a class that's invisible because it should be versus one that's invisible because we forgot to add the macro? NSClassFromString() has to be able to return all classes, including private, invisible classes. Otherwise the class code could never run.

Maybe there's a way to enumerate SourceKitten's generated public symbol list, mangle the symbols, and ensure that they have the right entry in otool output for the framework? Sounds really complicated.

@kkaefer kkaefer force-pushed the macos-sdk-symbol-visibility branch 2 times, most recently from e4ef4d4 to b4b3c51 Compare December 20, 2016 12:27
@kkaefer kkaefer force-pushed the macos-sdk-symbol-visibility branch from b4b3c51 to b7623c8 Compare December 21, 2016 13:10
@kkaefer
Copy link
Copy Markdown
Member Author

kkaefer commented Dec 21, 2016

I removed the extern/extern "C" keyword from the macro, and renamed it to MGL_EXPORT.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

build macOS Mapbox Maps SDK for macOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants