Ok so I have an app that I'm writing that uses a library that someone at work developed. I've included the xcode project in my project and included the output target of that project in my project's target as a framework. I also included the .a file in my target under the "Link Binrary with Libraries" folder. I also have put in the configuration window the header and library search paths.
The problem is that when I try and build the project, it says that symbols are not defined in my project and xcode won't build it. I'm not sure what I'm doing wrong, or if there is something that I'm missing.
btw... The library builds just fine on its own.
Thanks,
Robbie
Check these things...
1- In the target you want to link the lib... Right click -> Get Info -> General Tab, and make sure that the lib is listed as a direct dependency.
2- Select the .xcodeproj in your groups and files window and make sure that you have the library product (should end in .a) checked.
Related
Good Afternoon
I am trying to implement googles heatmaps into my map based project.
In this particular project, I get the following errors when trying to build.
failed to emit precompiled header '/Users/zachwilcox/Library/Developer/Xcode/DerivedData/OddJobs-gbnkfettubuccoheinzfovrqefub/Build/Intermediates.noindex/PrecompiledHeaders/OddJobs-Bridging-Header-swift_3WGH9SNI96Z2-clang_16JN3VASQHE4C.pch' for bridging header '/Users/zachwilcox/Desktop/OddJobs/OddJobs-Bridging-Header.h'
and a follow up that says
'Google-Maps-iOS-Utils/GMUHeatmapTileLayer.h' file not found
I'm not sure why this is happening because I created an entirely new project and did the same implementation and it worked perfectly. But when I run it on my existing project I get these two errors.
I have been researching this problem for a while now and I can't figure out what the problem is. I have the Bridging header set to the .h file.
I have tried most steps that individuals have tried to give with their answers but for some reason, it's not working for my project. Thank you in advance. When reading googles installation guide, it said that all I needed to add was one bridging header file which is the code you see in the image below. When researching it, I have seen that I needed to add a .m file as well however I still get the same error when I do. again, in my dummy project, I don't have the .m file just everything you see below and everything compiles.
There are chances you have 'Find Implicit Dependencies" turned off for the selected Scheme. If you have updated/installed pods and try to build the project, it will more likely fail if this option is unchecked for the selected Scheme.
From Apple's Document:
Parallelize Build – This option allows Xcode to speed up total build time by building targets that do not depend on each other at the same time. This is a time-saver on projects with many smaller dependencies that can easily be run in parallel.
Find Implicit Dependencies – This is a very powerful option that allows Xcode to resolve what targets need to be built for the primary target of the scheme to be built successfully. However, this does come with some sharp edges that you have to be aware of.
Situation: You link a library against your application target and create an implicit dependency to that library’s target.
Scenario 1: “Find Implicit Dependencies” is enabled.
Result: The library will get built prior to building the application target. The application target will then link against the library and build successfully.
Scenario 2: “Find Implicit Dependencies” is disabled.
Result: The library will not get built prior to building the application target. The application target fail to build.
Fix: To ensure that the second scenario does not happen, you must add the necessary targets into the targets list and order them correctly.
If your project includes pod then you've to set the pod configuration for the test project too..
Select Root Project in File inspector -> Project Name -> Info -> Configurations
Set configuration for your test project same like your main project
How to build a .bundle from source code?
This might sound like a simple problem but it has been hurdling me for a week...
Here is my problem:
I have a bunch of .c and .h files that are organized in a folder and its sub folders. The source code was written and compiled with gcc make and tested by many other make tools. The source code has some utilities and command line tools and it has more code that serve as library for those utilities and tools. It is the files that serve as libraries that I want to reuse. (By library I don't mean static library or something, I just mean that some .c and .h files in certain subfolders provide functions that can be called by some other .c files. I want to be able to call those functions, too)
Yet my problem is more complex than that: I need to build those .c and .h into a bundle to reuse it. I am not writing my application in C; I am developing in Unity and Unity can only take in .bundle files on Mac OS.
Here is my goal:
Organize the source code folder in a proper way so that I can build them into a bundle in Xcode 4.
Here is where I got stuck:
When building the project I got the following error:
Duplicate symbol _main in
/Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccndsmoketest.o
and
/Users/zeningqu/Library/Developer/Xcode/DerivedData/ccn-cfygrtkrshubpofnfxalwimtyniq/Build/Intermediates/ccn.build/Debug/ccn.build/Objects-normal/i386/ccnd_main.o
for architecture i386
I can relate to this error because I can find lots of main entries in the source code. Most of them are test utilities.
Here is what I tried:
I tried removing all those utility .c files but with no luck. The error is still there. I delete and delete until some files cannot find the definition of the function they are calling. So I had to stop there.
Though I wasn't able to build a bundle I was able to build a C/C++ static library (with an .a extension). After I got the .a file I tried to put it into another Xcode project and tried to build it into a bundle. I could build a bundle in that way, but then I had problem accessing the content of the bundle. How do I call functions defined in a .a static library if that library is hidden in a bundle? I read about Apple's documentation which says:
Note: Some Xcode targets (such as shell tools and static libraries) do
not result in the creation of a bundle or package. This is normal and
there is no need to create bundles specifically for these target
types. The resulting binaries generated for those targets are intended
to be used as is.
(quoted from: https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html#//apple_ref/doc/uid/10000123i-CH100-SW1)
Here is what I thought about:
I thought about replacing all main with something like main_sth. But the source code was not written by me so I didn't want to modify it. (It just doesn't feel like a proper way of doing things to me...)
I learnt that Xcode has gcc compiler built in. So I guess if gcc can make it, so can Xcode? It's just a wild guess - I am not familiar with Xcode and gcc.
Here is a summary of my questions:
Is there a way to properly organize a pile of code previously compiled and made by gcc make so that they can be built into an Xcode bundle?
Is it meaningful to put a .a library in an Xcode project and build it into a bundle? If it is meaningful, how do I call functions defined in .a after it is built into a bundle?
Is it proper to just replace all main() entries with something else?
Alright I think I have figured out at least one solution to the problem.
The duplicate main error was caused by a bunch of main entries in my source code. When the code was compiled by gcc make, I guess the author defined a sort of compilation order so that duplicate mains won't be an issue. (If you know how to do this, please let me know. I barely know make tools.) But when I just add the entire source code folder into my Xcode project, of course Xcode would complain during linking...
As I was unwilling to modify the source code (because the source code library is not developed by me), I decided to use another strategy to walk around this problem.
If your duplicate main error was reported from your own code, you can stop reading here. But if you are like me, with a bunch of gcc compiled source code and badly need a bundle yet don't know what to do, I may be able to help.
Okay here is what I did:
I set up an empty workspace.
I built a C/C++ static library project.
Import my entire source code folder into the static library project.
Set some header search path for the static library project.
Build the static library project. (Now I have a .a library which I could link against)
I set up another project, with a bundle target.
At the bundle project -> Build Phases -> Link Binary with Libraries, add the .a library that I just built.
At the bundle project -> edit scheme -> Build, add the static library project to the scheme and move it up the list so that it is built prior to my bundle project.
Then add .h files of my library project to my bundle project as references.
After that, add a .c file in my bundle project that basically functions as a wrapper. I picked a function that I want to call in Unity, wrote a wrapper function in the new .c file, and was able to build the bundle.
After several trial and error, I was able to import the bundle into Unity and was able to call the test function from Unity.
I was really excited about this! Though it's not completed yet I think this gives me hope and I am confident I can use the source code now! And the best thing about this solution is that I don't have to modify the library code developed by others. Whenever they update their code, I just update my .a library and that's it!
Though I have listed 11 steps I still feel that there are lots of details that I missed. So here are my references:
I followed this tutorial to build my source code into a static library: http://www.ccnx.org/?post_type=incsub_wiki&p=1315
I followed this blog to link static library against my bundle code and twist build phases and search headers: http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/
I followed this doc to import my bundle to Unity3D Pro as a plugin: http://unity3d.com/support/documentation/Manual/Plugins.html
I strongly recommend the second reference because that's what solved my problem!
Though the problem is almost solved there are still a few things that I haven't figured out:
I don't know if a wrapper function is at all necessary. I will try this out tomorrow and come back to update.
-- I am coming back to update: the wrapper function is NOT necessary. Just make sure you have all the headers in your bundle project and you will be able to use all the data structures and call functions defined in your headers.
I haven't used NSBundle class though I read a few docs about it. Previously I was thinking about using that class to access my .a library encapsulated in my bundle, but as I found the solution I wrote above, I didn't try the class out.
Lastly, if you have better solution, please don't hesitate to let me know!
I tried to follow the steps in the accepted answer, but had no luck. In the end, I realised step 10 needed to be modified slightly:
Create a dummy.c under (.bundle) project and the dummy.c can just be totally empty.
Remove the setting for the library you want to link inside Link Binary With Libraries
Instead use -Wl,-force_load,$(CONFIGURATION_BUILD_DIR)/libYourLib.a or -all_load to Other Linker Flags
PS: And also can use sub-project instead of workspace. and use Target Dependencies instead of Edit Scheme to achieve the same effect.
One of my Mac applications contains a framework which I embed into the application bundle. Now I have found some evidence that on some customer machines the application links against the same framework located in the /System/Library/Frameworks folder.
I'm obviously missing something when it comes to linking the embedded framework to the application in XCode, so here's how I've done it.. and perhaps you can point me to the missing step:
1) I drag the framework project into my project and set up the dependency between both projects
2) I drag the build product of the framework project to the "Link Binary with Libraries" build phase of my target
3) I drag the build product of the framework project to the "Copy Framework Files" build phase of my target set to "Destination: Frameworks"
This all works great but somewhere I need to specify that I want to link with the embedded version of the framework rather than any framework version that might be found on the system. Is there a search path to be set somewhere? or "static" link?
Any help would be appreciated.
Best regards,
Frank
Sounds like you might be missing a key step. You also need to set the "install name" of your embedded framework.
When you link a framework or dynamic library, your app will look for the framework at the path specified by framework's install name. This should specify a relative path for embedded frameworks. If it is an absolute name it will pick up the system installed version, even if you've embedded the library.
To examine the install name do the following and look at the first location.
otool -L <framework-binary>
These two blog posts explain the issue and also how to set everything up properly:
http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html
http://www.dribin.org/dave/blog/archives/2009/11/15/rpath/
Additionally, if you're compiling a dylib from the command line (say an open source library) just add the following to your CFLAGS to set your install name.
-install_name '#rpath'
If you want to modify an existing binary's install name use 'install_name_tool'.
Also be sure your copy files build phase is copying the right files into the right places in your app bundle.
I am trying to do this, and running into problems. The parent project needs to access the class SettingsViewController from the child project. I have put the child project path into my header search paths. Everything compiles OK, but I get linker errors, as follows:
Undefined symbols: "_OBJC_METACLASS_$_SettingsViewController",
referenced from:
_OBJC_METACLASS_$_StatisticsViewController in StatisticsViewController.o "_OBJC_CLASS_$_SettingsViewController",
referenced from:
objc-class-ref-to-SettingsViewController in SelectionViewController.o
_OBJC_CLASS_$_StatisticsViewController in StatisticsViewController.o ld: symbol(s) not found collect2: ld
returned 1 exit status
How can I fix this?
I assume the child project is a static library. Currently, your parent project knows how to find the header files of the child project (otherwise it wouldn't compile), but it doesn't know that it has to link to the library (.a) file of the child project.
You should probably add the library file to Targets > {your app} > Link Binary with Libraries. Furthermore, you probably need to add the linker flags -ObjC and possibly -all_load.
There are many detailed descriptions on the net, e.g. Build iPhone static library with Xcode.
Update:
If it's not a static library, then it's a rather strange project setup. The best thing you can do is to add the shared files (.h and .m) to both projects. They will then be independently compiled in both projects. That should work if you have few shared files.
But I recommend anyway to use a project setup with a static library. It nicely works if you properly set it up. I'm successfully using it. And - as I've told before - there a several good descriptions on the net how to set it up.
You may be missing a framework. Can't really tell from what you have posted here though.
I know this is very old but might be helpful for others.
You need to setup the included project in Target Dependencies in "Build Phases" to get the included projet to be compiled and you also should add the static library of the included project in the "Link Binary with Libraries".
Click on your Target->Build Phases and set these up.
Undefined symbols
Undefined symbols is a linker error
1.Check if you have added a library or framework
Project editor -> select a target -> General -> Frameworks, Libraries, and Embedded Content(Linked Frameworks and Libraries)
//or
Project editor -> select a target -> Build Phases -> Link Binary With Libraries
2.If you try to use Swift code from Objective-C
Add empty .swift file to the Objective-C project. When Xcode ask press Create Bridging Header
I'm working with an existing project that produces a dynamic library (Cocoa API).
I'd rather generate a static library, but if I change the
[Linking|Mach-O Type] field from "Dynamic Library" to "Static Library",
both the Clean Project and Build Project complain that the
target has an invalid MACH_O_TYPE value of 'staticlib'.
Is there a straightforward way to get the build to produce
a static .a file?
Thanks,
Eric
Opens up the project.pbxproj file in YourProjectName.xcodeproj folder using TextEdit, search for productType and change it's value from "com.apple.product-dynamic" to "com.apple.product-static"
I ended up creating a new 'static library' project, and then added all
the members. Closing xcode and bringing up the two project files in
a text editor let me quickly complete the new project.
I managed to do this, with the help of this post and a bit of digging around. Additional changes I had to make were changing compiled.mach-o.dylib to archive.ar and changing various references in the project file (including inside comments, call me pedantic) from foo.dylib to libfoo.a.
I also had to create a new 'scheme' before it would build, but that might be because I changed the name of the project, I'm not sure. Also, any frameworks referenced by the library need to be added to the application(s) that link against it when you move from .dylib to .a.
It was well worth persevering though as it preserved all the subtleties of the original project (such as building a 32/64 fat binary for release but not for debugging). Result.
Delete your build target, then create a new one, choose "Library" and make sure you choose type "Static". After this, you only have to add your sources and dependencies again.
You have to change two settings:
Under Library, set Mach-O Type to Static Library
Under Packaging, set Executable Extension to a
This worked for me on Xcode 13.1.