I have looked into these kind of errors on posts but most of them have an _OBJC_CLASS name that you could track down. This error looks different.
-(void) initLocal
{
m_pScanner = new CScanner(self);
}
and the class looks like:
class CScanner : public SmartcodeDecoder::Observer {
public:
CScanner(void* pControler);
};
The error looks like the following image:
The linker can't find the definition of function CScanner::CScanner(void*). The code above shows a declaration of that function, but not its implementation. Find the source code file or library that implements that function, and make sure it is added to the project.
As Eugene noted, the linker warning about mismatched architectures is suspicious. It's possible that the implementation of CScanner::CScanner(void*) is present for some architectures but not for i386 (which is the one you're trying to build).
Related
There are a lot of questions about this on the web but I couldn't solve my problem. I've been studying this for a few days.
I want run a simple C++ class on Swift project, to this I followed this tutorial: http://www.swiftprogrammer.info/swift_call_cpp.html.
Basically I've followed the steps:
Create junk.cpp and junk.h files
Compile using g++ or/and clang++
Create .a file with: $ ar r libjunkcpp.a junk.o
ranlib libjunkcpp.a
Linked to Xcode in Build Phases -> Link Binary With Libraries -> Add
When I compiles, the follow errors occurs:
Undefined symbols for architecture x86_64:
"A::getInt()", referenced from:
_getIntFromCPP in wrapper.o
"A::A(int)", referenced from:
_getIntFromCPP in wrapper.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
junk.h
class A {
public:
A(int);
int getInt();
private:
int m_Int;
};
junk.cpp
#include "junk.h"
A::A(int _i) : m_Int(_i) {}
int A::getInt() {
return m_Int
}
wrapper.cpp
#include "junk.h"
extern "C" int getIntFromCPP() {
// Create an instance of A, defined in
// the library, and call getInt() on it:
return A(1234).getInt();
}
bridge.h
int getIntFromCPP();
This is an issue that sometimes occurs when using C or C++ libraries that get bridged through Objective-C into Swift. The issue isn't with how the Archive (static library) is built -- rather, it's a problem with an overly-aggressive linker creating the application.
The problem is that the linker sees the binding symbols and the C++ symbols, but never sees it being called from anywhere because it is actually invoked from a different language (Swift). This ultimately results in the linker aggressively stripping all symbols that it doesn't believe are being used in an effort to save space, which effectively removes all of the C++ code.
When this happens, nm will report the correct symbols as existing in the archive, but the actual application will fail to execute due to the symbols not being found.
As for solutions, there are actually several questions/answers already on Stack Overflow that address this issue in varying degrees:
How to disable C++ dead code stripping in xcode, where the solution is to use the linker flag -force_load to force that the static symbols are actually loaded.
Keeping Xcode from stripping out unused symbols from a static library which suggests using __attribute__((constructor)) to trick the linker into thinking the symbols are needed on construction, thus keeping them in.
Xcode Archive debug strip errors, which more broadly suggests toggling some Xcode configurations that may result in the symbols not being stripped. The suggestions in the answers here may conflict with the above two links, however.
It is difficult to provide a definitive and clear answer without more information on the existing setup, such as where wrapper.cpp is built, and how the bindings get used from within the Swift project. Given that this question is from 2018, I don't suspect there will be much more information on what this setup was at the time.
From the described symptoms, this sounds exactly like the issue my colleagues faced when doing C++/Swift bindings -- and the solution was ultimately to use -force_load which ensures that the archive is preserved in totality into the final application.
I have taken this example directly from a book on C++ (shortened it so it's easier to see what the problem is).
My class won't compile with g++. The class is:
class stack{
private:
int count;
public:
void init(void);
};
inline void stack::init(void){
count= 0;
}
~
As you can see, I'm trying to prototype my functions inside the class, then define them outside the class. The book did exactly what I am trying this, but it doesn't work. Where is the mistake? Is it my computer (I'm using a mac). The error I get is the question, but also here:
user-MacBook-Pro:cplusplus trevortruog$ g++ Stack2.cpp
Undefined symbols for architecture x86_64: "_main", referenced from:
start in crt1.10.6.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status
The code compiles fine. It just doesn’t do anything useful since it’s missing a main function and therefore no executable can be generated from it.
This is not an error in the compiler but rather in the linker, which precisely complains about the lack of an entry point. You can see this from the error message:
ld: symbol(s) not found for architecture
The first thing, ld, is the name of the application which created the error message. ld is the linker application which is (internally) called by the actual compiler. Once that gets called, the code is already compiled.
Add a main function to solve the linker error.
As an added comment, the code uses bad practice. This is a sure hint that the programming book you’re using is bad. Unfortunately, bad teaching material is the bane of C++, which is a highly complex language even when taught correctly. Do yourself a favour and ditch the book in favour of a good one.
I am having a persistent undefined symbol error in Eclipse on MAC OS X. I can't figure
out the source of the error.
The error occurs according to the compiler when I try to use GA_Operations and gaAlgorithm->run_algorithm..... below:
int Application::execute_Algorithm()
{
if (this->GA_On)
{
GA_Operations *gaAlgorithm = new GA_Operations();
gaAlgorithm->run_algorithm(blocksSequence, bins);
}
else
{
packingAlgorithm->run_algorithm(blocksSequence, bins); return 0;
} //
return 0;
}
The error showing is:
Undefined symbols for architecture x86_64:
"binproject::GA_Operations::run_algorithm(binproject::Blocks_Sequence&, binproject::BinContainer&)", referenced from:
binproject::Application::execute_Algorithm() in Application.o
"binproject::GA_Operations::GA_Operations()", referenced from:
binproject::Application::execute_Algorithm() in Application.o
And the declaration is:
class GA_Operations {
public:
GA_Operations();
~GA_Operations();
//call from main application to execute algorithm
void run_algorithm(Blocks_Sequence &b_seq, BinContainer &container);
...
};
It also throws a similar error anytime I try to define a declared function in the
implementation (CPP) file.
Any ideas? This only seems to happen with this class.
Also, I apologize if there is a problem with the code indenting, I'm
The error you are showing is a linker error. This means that the compiler thinks something exists, but the linker can't find where you've defined (not declared) it. Somewhere you need something like this:
GA_Operations::GA_Operations()
{
// construct
}
void GA_Operations::run_algorithm(Blocks_Sequence &b_seq, BinContainer &container)
{
// stuff
}
Do you have that anywhere? If so, is it in the same file that Application::execute_Algorithm is in?
If it isn't, where is it? How are you compiling your whole program together so the stuff in these different files ends up in the same executable?
I'm not at all sure how to make Eclipse do what you need. I know it's possible, but I'm for familiar with pure command-line tools. You need to tell Eclipse that the .cpp file that contains the above definitions is part of your project and should be compiled and linked into the executable you're created.
Turns out this was an issue with linker settings. I turned on generating makefiles automatically and the problem resolved itself.
I have Core static library, a few Component static libraries that relays on the Core one, and then there is an App that links against both Core and Component libraries. My App can link both against Core and Component as long as Component don't uses classes from Core (App uses classes from Core).
I got the following error in both armv6 and armv7 versions. So my problem is not the very popular linking issue that everyone has.
ld: symbol(s) not found for architecture armv6
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I added reference to Core in Component and even added it in "Link Binary With Libraries" which shouldn't be necessary for static lib.
Since I start having this issue I start doubting my design... It probably makes more sense in dynamically linking environment but still it should be doable in static one, especially since this already works under Windows with MSVC compilers.
Edit:
I made some progress! Although I still don't know where to go with it.
Here is my setup:
Core has a class cResourceManager that has a templated method GetResource<T>(int id)
Core also has class cResource
Component has class cMesh that inherits cResource
Here are some tests:
If I try from App to call rm->GetResource<cMesh>(...) I get the linking error
If I try from App to construct cMesh I get linking the linking error
If I try from App to call static method that will return new instance of cMesh I get the linking error
If I comment out the construction of cMesh but leave other member cMesh function calls the App links fine. I can even call delete mesh.
I have never seen anything like it!
If you remove the cMesh constructor, then you are then using the default (no argument, no body) cMesh constructor that is given to you. It almost sounds like there's a build error or missing code as a result of some code in your cMesh constructor and so the library isn't actually getting generated, and perhaps Xcode isn't reporting the error. Xcode is no good at reporting linker errors.
I would suggest looking at what symbols the linker says are missing and double-check that they are actually defined in your code. My guess is that you're using one of those symbols in your cMesh constructor. A lot of times with virtual base classes, you may forget to define and implement a method or two in a child class. Could be a result of missing a method based on your template, or your template isn't #included correctly. This could compile fine but result in linker errors like you're seeing.
If Xcode isn't showing you the full linker error, show the Log Navigator (Command ⌘+7), double-click the last "Build " entry, select the error, and then press the button on the far-right of the row that appears when selected. The symbols should be listed there. If not, it's time for xcodebuild in the Terminal.
If it's not that case, I'd be interested in seeing the results of whether or not the library is being built for the appropriate architecture, or maybe this can spur some progress:
In the Xcode Organizer Shift ⇧+Command ⌘+2, click Projects and find the path to the DerivedData for your project.
In the Terminal, navigate to that directory (cd ~/Library/Developer/Xcode/DerivedData/proj-<random value>/)
Remove (or move aside) the Build directory (rm -r Build)
In Xcode, try to build with the cMesh constructor present.
Find the Library product file (cd Build/Products/<scheme>-iphoneos)
Your compiled static libraries (<libname>.a) should be in this directory. If they're not there, they didn't build (unless you put your products elsewhere). If your libraries are there, let's confirm that they actually are getting built for the appropriate architecture. Run otool -vh <library>.a. You should see something like:
$ otool -vh libtesting.a
Archive : libtesting.a
libtesting.a(testing.o):
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC ARM V7 0x00 OBJECT 3 1928 SUBSECTIONS_VIA_SYMBOLS
As you can see, my test library was built for ARMv7.
Make sure you are linking them in the correct order.
If Component depends on symbols in Core, then Component needs to be first in the link order, so the linker knows which symbols to look for in Core.
In MSVC the order doesn't matter, but in most other compiler suites it does.
I don't think Clang generates code for armv6, if you're targeting devices that old you still need to use GCC.
There is a static class Pipe, defined in C++ header that I'm including.
The static method I'm interested in calling (from Objective-c) is here:
static ERC SendUserGet(const UserId &_idUser,const GUID &_idStyle,const ZoneId &_idZone,const char *_pszMsg);
I have access to an objective-c data structure that appears to store a copy of userID, and zoneID -- it looks like:
#interface DataBlock : NSObject
{
GUID userID;
GUID zoneID;
}
Looked up the GUID def, and it's a struct with a bunch of overloaded operators for equality. UserId and ZoneId from the first function signature are #typedef GUID
Now when I try to call the method, no matter how I cast it (const UserId), (UserId), etc, I get the following linker error:
Ld build/Debug/Seeker.app/Contents/MacOS/Seeker normal i386
cd /Users/josh/Development/project/Mac/Seeker
setenv MACOSX_DEPLOYMENT_TARGET 10.5
/Developer/usr/bin/g++-4.2 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk -L/Users/josh/Development/TS/Mac/Seeker/build/Debug -L/Users/josh/Development/TS/Mac/Seeker/../../../debug -L/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib/gcc/i686-apple-darwin10/4.2.1 -F/Users/josh/Development/TS/Mac/Seeker/build/Debug -filelist /Users/josh/Development/TS/Mac/Seeker/build/Seeker.build/Debug/Seeker.build/Objects-normal/i386/Seeker.LinkFileList -mmacosx-version-min=10.5 -framework Cocoa -framework WebKit -lSAPI -lSPL -o /Users/josh/Development/TS/Mac/Seeker/build/Debug/Seeker.app/Contents/MacOS/Seeker
Undefined symbols:
"SocPipe::SendUserGet(_GUID const&, _GUID const&, _GUID const&, char const*)", referenced from:
-[PeoplePaneController clickGet:] in PeoplePaneController.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Is this a type/function signature error, or truly some sort of linker error? I have the headers where all these types and static classes are defined #imported -- I tried #include too, just in case, since I'm already stumbling :P
Forgive me, I come from a web tech background, so this c-style memory management and immutability stuff is super hazy.
Edit: Added full linker error text. Changed "function" to "method". Also I'll note that we're using a custom makefile to compile a few projects external to this one. SocPipe static methods are referenced elsewhere, though, in this xcode project and seems to compile fine.
(Eh, let's turn that comment into an answer.)
The method signature looks fine; that is, what you're calling matches what is declared in the header. If it was not, you would probably be getting a compilation error rather than a linker error.
The linker's problem is that it doesn't have any corresponding object code to connect this call to: the method is declared but never defined.
The latter should occur either in a C++ source file which your project can compile, or else in some precompiled library or framework that you can link to. Either way, that file needs to be included in your project so that it can be made available to the linker.
The object file containing Pipe::SendUserGet is not being built, or it is not being linked into your Xcode target. Whether or not other static methods in Pipe work correctly is not necessarily relevant if those methods are defined in the header file.
You mentioned that you use external makefiles to build parts of your project. In that case, it's not enough to run the makefile at compile time as a dependency — you also have to include the resulting products in your project.
For example, if you have a makefile that builds libLIBRARY.a, then drag libLIBRARY.a into your project and add it to your target.
This only works if the makefile is building a library. It won't work if the makefile builds a program. It also gets more complicated if the library is a dynamic library, as you'll also have to make sure that the dynamic library gets distributed with your application (often by putting it in the app bundle, if you're making an app bundle). It also gets more complicated if you want to build a universal binary. You could theoretically pass the right CFLAGS to make to build a universal library, but it may be easier to run make once for each architecture and combine the results using a script (which is what I do).