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
0.36.0.Beta.2: Pods-Framework-umbrella.h generation breaks LLDB symbol lookup #3092
Comments
The generated umbrella header is under your own control, only public headers will be added to it. For your Pod, you can use:
to no longer include |
Thanks for your response, @neonichu , but there is actually more nuance to this problem. It is not simply a manner of making an umbrella file private (that would serve no purpose). The crux of it is that:
From digging deeper, I see this as three things:
The non obvious (to me) work around, is to ignore the form described in Xcode's generated umbrella file and import files using double quotes instead of angular brackets (I realized this distinction after posting the original bug). Many people will fall victim to this (following the directions). That, and this still leaves the framework author with having to generate what cocoapods is now smart enough to do on it's own - the umbrella file for the normal, established use-case of My points in summary are that For now, I highly recommend updating Cocoapods guides to direct people to ignore Apple's guidance and not use angular brackets in any umbrella or otherwise public header they have. I also recommend that Cocoapods default to the expected As it is now though, there are a number of posts on stackoverflow struggling with this and issues like this. Thanks! |
To your point 3.ii: it is best to also use the module import |
Good point, that is the best (only good) approach as it pulls in the Swift symbols as well - something worth emphasizing in guides and docs. |
I don't know how or why, but in two separate test projects I have seen that Xcode will still try to reference an Umbrella file of the expected Here is what I did to filter out the existing umbrella file:
Here is my spot check afterwards:
Obviously when I removed the file from the project directory, it did not appear at all. In either case though, the result was the same, Swift / Clang / Xcode would try to include it in Framework-Swift.h:
Hopefully this is just something that I am missing (I did nuke the Pods and DerivedData directories though). Also, is there a setting for "Defines Modules"? This needs to see Objective-C code in Swift, within a framework. I will attach an updated zip illustrating the problem with include of the phantom umbrella file. |
Here is the link to the project without the umbrella file, that fails to build. I could well me missing something, but I don't know why Xcode / Clang would be including that header, or what the mechanism is for that: https://www.dropbox.com/s/trwtwt2nbd7o0oh/FailsWithoutUmbrellaFile.zip?dl=0 Thanks -c |
Good catch! It appears that |
This shows the full invocation which generates it: https://gist.githubusercontent.com/neonichu/366b2b10aa5b49ec3b82/raw/36b1b2a9b1dd07b74b5fb9d2caf230b7e318b1a9/emit-header.sh - obtained by putting a logging shim in place of swiftc. |
I think I traced this one to the source and it should be easy to fix. I was originally diverted by the error message, thinking it was reporting the familiar problem that a non modular
Evidently, Xcode / LLDB was actually reporting that it found a non modular header in the search path, and it wasn't happy with this. Specifically, it was finding the headers stashed in the
directories when it expected to find them in the build output directory. I then trace this problem back to the Pods-Mixed-Private.xconfig file, specifically the line:
In my testing, this is not needed, as the framework is built first, and the project then finds the necessary testing in the framework's include path. This could use more testing, but I think the best final fixes for this bug are to:
I think trying to solve the problem wherein swiftc / Xcode includes the non-existing default umbrella file is a red-herring and a case of solving the wrong problem. If #2 above solves two problems simply and elegantly (and without breaking convention), then it is the best choice. Put the other way, it's hard to argue for putting a lot of effort into a solution that breaks the convention and complicates the easy case where the user/client just "wants it to work" without having to create a redundant umbrella file. I don't know this codebase or speak Ruby, but I think the above changes should not be difficult. It should be more of a problem of removing logic that we don't need. |
Thanks for your findings! I'm still torn on generating the framework header with the default name, because there can already be a header in the user's codebase which has a naming conflict with it. This can raise some backwards compatibility concerns, because there used to be no special technical meaning to this header file. |
Can you see any drawbacks to this approach?
I cannot see how this could break any legacy projects, and would be the simplest in the simplest case. If someone already had an umbrella file by that name, then cocoapods could note / log that fact, and follow the current form of Really though, if you're using cocoapods to create a framework, then you're much better off treating cocoapods as the "one source of truth". The alternative is worse in every way. You would have to first create a project simply to create the otherwise unnecessary umbrella file. To make this umbrella file complete, you should really copy the contents of the generated umbrella file to get all the public includes. This is a lot of effort for something that could work out of the box. In short, the Thanks! |
It would be nice to split this one apart, and at least remove the conflicting search path entries that point to the local Pods. The question of what to do about the Umbrella file generation can be left to later, but the search path issue would seemingly be a simpler fix and would help a lot of people. Also, I should / need to write this up as a second bug, but it appears that Cocoapods erroneously treats private headers as a negation of public headers, when in fact, they are intended as a secondary, internal interface useful for debugging and the like - and not meant to be exposed to the final consumer. Currently cocoapods uses the private-header path filter as a means of filtering out public headers, but they are two concepts and deserve their own negative filters. And I posted this to #3062, but at least in Xcode 6.3 beta, the Swift compiler is defaulting to optimize code for Debug builds, which is wrong (slow to build, and harder to debug) |
Some changes to how we treat private headers in frameworks will be done via #3145 |
Can / should we split this into a separate issue for removing the pods-level search paths, or could just this portion be fixed? That would fix the LLDB errors and potentially enable symbol lookup (Xcode permitting). The separate issue of the umbrella file override could still be an Xcode bug, and is possible to work around. But out of the gate, it seems imperative that Cocoapods doesn't break anything obvious - the erroneous header includes (detailed above). If just these could be removed, then it would unblock debugging - at least to the extent that Xcode supports it. Thanks. |
There is a new wrinkle with umbrella header file generation. Xcode / Swift wants you to include / import the -Swift.h file within the umbrella file and warns if you don't, but at least in my testing of the linked project, I get an error only with Cocoapods due to build order in that it is trying to consume the umbrella file that and consequently -Swift.h file, before the -Swift.h has been created. As a workaround, if you don't try to include the -Swift.h file, it will build fine and the Swift.h file will be generated. You can then modify the umbrella file and it will continue to compile. This is in contrast to the direct / non cocoapods case, where it will generate the -Swift.h file before consuming the umbrella file. I'm not sure where it's coming from, I just know that it is different than the non cocoapods case. So two things, the -Swift.h file should be included in the generated umbrella file, and the build order needs to be fixed so that the -Swift file is generated before the umbrella file is consumed (and this is strictly while building the framework, not the client that consumes the framework). |
Bump, this is blocking for me with transitive mixed framework dependencies. More info : If framework A depends on B and both are mixed, xcode generates -Swift files If B.h is imported before any other header in B-umbrella.h a non-modular header import is triggered in xcode. The detection of an existing umbrella header or creating a default one proposed above seem a great solution |
Closing as a duplicate of #3767, which describes a plan of action. |
@segiddins Should this issue be closed based on #3767? |
Yup! |
Description
Using Cocoapods 0.36.0.Beta.2, you can build a mixed language framework, and run it in a client.
However, symbols are not available in the client, with LLDB giving errors like this:
It is interesting to note, that deleting this line from the file generated in the build output directory like:
does not break the building process, but does allow client code to see both Swift and Obj-C symbols in the framework. I am not sure if this amounts to complete symbol information, but it is a pronounced improvement:
Also note, that the existing bug #3062 in which cocoapods incorrectly strips symbols during deployment of debug builds, exposes a crash bug in Xcode during symbol lookup. To get the symbol data above, and to avoid Xcode's crash bug, you must first clear the strip-symbols on copy setting.
Steps to Reproduce:
Download project at this link:
https://www.dropbox.com/s/trhe5vwhzoa9bf5/umbrella_file_breaks_symbol_lookup.tar.gz?dl=0
Run app, it should stop at the break point on
println("done")
:type
po swiftFoo
, as abovesee baseline, broken case as in first output
Steps to Workaround
"Mixed.h"
po swiftFoo
, note that symbol lookup now works.This may well be an Xcode bug, but the fact that you deleting the include fixes the debugger issue while not affecting the build, suggests that this problem can be avoided.
The text was updated successfully, but these errors were encountered: