Link error while building a unit test target
Solution 1
Make sure that the FRRCategory source file has been added to your Compile Sources for your unit test target.
Xcode 4:
Project Navigator -> "[Project Name]" -> Under Targets select your unit test target -> Build Phases -> Expand Compile Sources -> Click + at bottom of Compile sources and add the correct source file.
Solution 2
Follow the instructions here. It doesn't require you to add any files to compile sources.
I first missed that "Symbols Hidden by Default=NO" should be for your app target, not test target.
It worked for me anyway (tm).
Solution 3
Another gotcha that you may hit is if your unit test is using C functions (or similar) that aren't used in the actual app.
This may be restricted to having a sub-project. In my case
- App
- Sub-project
- A C library embedded (i.e. .c and .h files compiled directly inside)
- Sub-project
My unit test used a few of the C functions that were not used anywhere else, and these were stripped from the app binary (NOT from the sub project's .a file).
The fix is to
- turn off "Dead Code Stripping" for the app's Debug build.* and
- make sure your unit tests are using Debug and not Release, in the Scheme settings.
(* don't do this to the release configs as it'll bloat the app with code that is never called).
Solution 4
You should only refer to a folder inside your import if your file is inside a framework. Otherwise, once you added your file to the project, simply do #import "FRRCategory.h"
. Well, unless you did something weird with your Header Search Paths.
![cfischer](https://i.stack.imgur.com/QH4NK.jpg?s=256&g=1)
cfischer
Updated on November 10, 2021Comments
-
cfischer over 2 years
I have a XCode4 / iOS project with a regular target and unit test target. Everything works fine, except when I try to #import one of my classes in my test class and try to use it. If I try to build the unit test target, I get the following link error:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_FRRCategory", referenced from: objc-class-ref in CategoryTests.o ld: symbol(s) not found for architecture i386 collect2: ld returned 1 exit status
In CategoryTests.m I'm importing the header file in this way:
#import "../todoro/FRRCategory.h"
What am I doing wrong?
-
cfischer about 13 yearsAdding the files to the compile sources removed the error. What are those "compile sources" anyway and what's the rationale of forcing you to manually adding files from your main target?
-
cfischer about 13 yearsIt didn't remove the error, but I had no idea it wasn't necessary to include the folder. Thanks!
-
Jano about 13 yearsEach target uses an independent set of source files. Either you didn't create the test target as a duplicate of your main target, or during the creation of
FRRCategory
you didn't select both targets. -
Jon Reid about 13 yearsIt depends which unit testing framework you're using. Are you using SenTestingKit that comes with Xcode 4, or something else? …If you're using SenTestingKit, then you don't want to add the code under test to your test target.
-
Joe about 13 yearsCompile sources are all of your implementation files that you need to have compiled for a target. When you have multiple targets each maintains there own set of compile sources and when you go to add new or existing files to the project you should see a checkbox option for which targets that new file should be included in. This includes resources such as images and interfaces as well code.
-
febeling almost 13 yearsThis the answer most people want to follow imo, not the one the questioner checked. This way the the application build product is build like for standalone use, and the tests link against it. The alternative is to replicate all build settings, linker settings, etc. to build the source separately with the unit test.
-
carlos almost 13 yearsThis is not the correct answer to this issue imo. Check answer below this one.
-
ColdLogic almost 13 yearsLol, even after reading your comment I still messed up and needed the "Symbols Hidden by Default=NO" on my app target, not the test one. +1
-
scorpiozj almost 13 yearsit helps. And I found the sample code of Apple has the same settings.Thanks!
-
Robert Gowland over 12 yearsThis answer works, but is painful if you're testing more than a couple classes (which I hope you are). See @Martin Wickman's answer.
-
Joe over 12 years@Ertai I agree the answer below is now correct and I as well have upvoted it months ago. But do note the difference in dates between to the two answers. Maybe consider convincing the OP to accept the other answer rather than continually downvote this one.
-
Tom van Zummeren about 12 yearsIt worked for me as well! I also think this is the only correct answer! Not the one marked as the correct one above... The one marked as correct is only a hack to get things kind of working.
-
mxcl over 11 yearsThis is indeed the only correct answer. The other answers compile two copies of your sources into what becomes the instantiated test bundle. While generally this will be fine, if there are bugs in the build-toolchain you would get very strange and hard-to-debug side-effects.
-
Max Seelemann over 11 yearsThank you, this is the first thing that helped!
-
qnoid over 11 yearsSince the question specifically relates to Unit Testing, following the guide on the link contradicts Apple's one developer.apple.com/library/mac/#documentation/DeveloperTools/…
-
Hulvej almost 11 yearsthe answer below is by far the best answer, especially if you have many sources
-
vpathak over 9 yearsWhile following the list of steps here, just make sure you add a cocoa touch test target (he says cocoa test target). had some issues with architecture type before adding the cocoa touch test target instead of cocoa test target
-
phatblat over 9 yearsThe linked post above helped me to resolve this issue in Xcode 6.2 using the Quick framework for tests. In my case, only the BUNDLE_LOADER build setting had to be set.
-
nazbot about 9 yearsTHIS IS THE WRONG ANSWER - see below. Don't mean this as rude to the answerer, just trying to save other people any wasted time in case they miss it.
-
xySVerma about 9 yearsSymbols Hidden by default = NO for debug mode solved the problem even for X-Code 6.3 for my newly added test target. Thanks.
-
amleszk almost 8 yearsThis was this issue when trying to run unit tests on device architecture arm64. Thanks
-
yurgis about 7 yearsthis solution does not seem to work for extension unit tests, more solutions are here: stackoverflow.com/questions/24627600
-
Amit Battan almost 7 yearsnot work for me :( I have static library need to write unit test. Code compile and build successfully but test case fail unrecognized selector. It works fine when I add .m file in test target