Static library inside iOS Framework error

I have created a framework which uses static library within it. The import statements of static library is giving error when i tried to use this framework in swift project.

All import statements of static library says file not found and framework is throwing error "Could not build Objective C module framework"

Replies

Your description is very general, so it's hard to know what's going on. It sounds like you have an app (Xcode target A) that links against a framework (target B) which uses a static library target C. It also sounds like target A is Swift, target B is Obj-C (or plain C), target C is Obj-C or plain C.


If that's correct, you cannot import library C into app A, because the library is part of framework B. It is linked into the rest of B's object code, and its separate identity as a library is lost. In app A, you would "import B" to use the functions from both B and C.


There are a couple of other possibilities:


— It may be that your framework B is just failing to link, because it's failing to find C at link time ("Could not build Objective C module framework").


— It may be that your framework B is not exporting the header files for library C, so they are not exposed to app A. When building a framework, you need to choose the "private" or "public" options for header files so that they get copied into the framework's internal Public or Private Headers subdirectory. (The default is "project", which means that the header files are not copied into the built framework.)


If none of this helps you, then I suggest you post the actual import statements you're using, and the actual error message produced, and where they are produced. Keep in mind that you may have two smaller errors rather than one big error.

Yes you are correct. App A is in swift, which uses Objective C Framework B. Framework B internally having Static Library C (Objective C). Framework B is having imports like

#import <LibraryC/library.h>

which is giving error while importing 'import "FrameworkB"' in App A.

Yes its failing to find C at link time. If i copy header files public of Library C to Framework B will it work? I tried once still import statements of Library C in Framework is giving error.

A static library is nothing like a framework. When you use library C in framework B, B completely swallows C, and C doesn't exist any more as an entity separate from B. So, your app A doesn't have any knowledge of C (except, of course, that if B makes functions belonging to C public, then A can see those functions, but as part of B, not C). Does that make sense?


So, if your problem that C is not found when creating the framework B, then the problem is in the way B is configured, and has nothing to do with A at all. You would need to solve that problem before you can know whether A has a separate problem.


In Xcode, you should be able to set B as the current target. You do this by select B's scheme from the popup menu in the status bar, over on the left side next to the Run and Stop buttons. With B as the current target, you should be able to build (Product menu -> Build) B with no errors. You should try this, and see whether B builds without errors. If there are errors, you have a problem in B that needs to be fixed.


If there are no errors then B is (probably) fine, and you will need to move on and investigate what is going wrong with A. But one step at a time ...

Yes Framework B is building fine. The same Framework B i added in the Application Project A (Swift). It throws compile time error. "Could not build Objective C module framework" & the class inside Framework which imports Library C headers showing "File not found" error.

Well, now it gets difficult, and it's unlikely we'll discover the solution in this thread except by lucky guesswork. Otherwise, you're likely going to need to take apart the build process step by step.


When you try to build your app, what device are you building it for? What device did you build your framework for? Note that the device is chosen from the right half of the scheme popup menu that we mentioned before.


My guess is that you built the framework for an actual iOS device (either a plugged-in piece of hardware, or the generic device), but you're currently building your app for the simulator — or vice versa. That would explain why building app A triggers an attempt to re-build framework B, although B already exists. For some reason, building B for the simulator fails. (An iOS device build uses the iOS platform. A simulator build uses the macOS platform, because the simulated app is actually running under macOS.)


One possible reason for that is that you've built library C for an iOS device, and configured B to always use that library, even when B is being re-built for a simulator. The link would fail (library C would contain ARM machine code, B would need Intel machine code), no module would be built for B, and building app A would also fail.


You could test this particular theory by building app A for whatever device worked for building framework explicitly.


It's also possible that this particular settings mismatch is not the cause, but something roughly similar, that also causes B to use the wrong settings. It may be that when adding library C to the target for B, or adding framework B to the target for A, you haven't set the file reference to "relative to build products". Using an absolute or project-relative reference might well cause either build to fail.


Or maybe … maybe … maybe … . There are a lot of possibilities.


Probably your next step is to start examining the build transcript (Report navigator) in detail. There may be more comprehensive error messages in the transcript than is reported as the final build status.

I cross verified Library C is a lipo file (simulator and device). Framework B is a simulator file and i am building in App Project A with simulator.

Is there anything to do with modulemap? I tried App project A as a Objective C project. Still seeing the same error.

If i remove Library C from Framework B then A is working fine.

Lipo-ing files from different platforms (simulator and device) isn't supported, but I don't know whether this has anything to do with your problem. It's certainly possible that C is being treated as an iOS library, and that's why it won't link into B. You could try building C for the simulator only, without using lipo, and see if that changes anything.


>> Is there anything to do with modulemap?


Look at the build transcript to see if it got as far as trying to create a module map for B. (My guess is that it did not.) The later error message about the missing module map may just be a secondary error, because the build of B never finished.


>> If i remove Library C from Framework B then A is working fine.


That's actually good news, because it narrows the problem down.


Is there any need to use a static library? At this point, it may be quicker and easier just to compile C's files directly into B.

I tried just a simulator file for C library. Still same problem.


Read somewhere need to add the header files of C library in modulemap, not sure its correct or how to do that.


Problem is when i add the Framework B in Project A, Library C import file are not referenced, and it is showing missing file error, so import B is showing error.


You can create a simple Libary C, Framework B and Project A to check this issue. I think main structure is having problem.


Yes, I just tried it and it doesn't work.


The problem appears to be that there's a conflict of roles for the library C header files, as being both the internal interface from B to [the parts of B that come from] C, and as being the external interface that exposes C's symbols to A. It's not clear that there's any solution.


If library C contains only C-language declarations, you might be able to work around this by replicating the public declarations in B's header files. However, if library C contains public class definitions, you can't duplicate the declarations without creating duplicate symbols.


Note that this is a problem only because you're trying to access C's symbols directly from A. So, another workaround would be to write wrapper functions in B to "publish" the relevant behavior to A.


Or, as I suggested before, compile C's source files directly into B, rather than trying to link a library.


Or, build C as a separate framework rather than a library, then link B against C, and A against both B and C.


Sorry, that's all I've got.