How to suppress undefined symbol error in C++? - c++

I am looking for a way to suppress/satisfy the linker when a symbol is undefined at compile time.
To illustrate what I am trying to accomplish I will put up a simple example:
CoreCpp.h file:
#include <stdio.h>
int calculate();
CoreCpp.cpp file:
#include "CoreCPP.h"
int calculate(){
return 0;
}
With these two files above I will create a .a static library.
Then in Xcode I will create a simple command line project as you can see in the image below:
If I link the static library, the project will compile without any issue of course:
However, if I don't link the static library, it will throw an undefined symbol error.
Undefined symbols for architecture x86_64:
"calculate()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
Question: Is there a way that I can suppress the error or somehow make the linker happy at compile time? Can we apply the concept of weak linking here?

I'm not familiar with Xcode, but its compilation/linking process should be similar to Eclipse. So first you should understand the differences between compilation, linking, and building. Then you should also realize that there are 2 ways of building your project: either compile your source code files separately and then link them together to get machine-executable instructions, OR to compile and link in one single step/command. In the step of compilation only, you can either get an output of a static or dynamic library, or a .o object file, which will be used later in the linking step. With separate steps of compile/link you have more control over your build process. What Eclipse (and supposedly Xcode) is doing when you build your project, is either of those 2 ways, depending on your project settings. If you'd like to take a full control over the process of building in Eclipse or whatever IDE you have, you should take care of your project settings, or even better to set it up to work with a Makefile, where you can define exactly how your source code should be compiled and linked and in which steps/order. In Eclipse you need to create a Makefile-project and edit your Makefile alongside the project files.
In this your question above, what you were trying to do (or asking for help) is forcing the IDE to build your project without specifying the library, for which obviously your linker was complaining about. Instead, if you specify the library it doesn't complain any more. But be careful, you should make sure your IDE settings are fine to (re)compile your library from its source upon changes, otherwise you may end-up linking an old version of the compiled library file with your main.cpp and other files.

Related

Why do I get errors when I link to a library, but not when I build it?

I'm working on an external module for a c++ library (ITK), which I'm building with cmake and make (I'm on an Ubuntu VM).
Let's say there is an error in the code, such as redefinition of a method. In this case, the library builds without errors with cmake ../src && make && sudo make install, but I get an error when I try to link a project against the library.
Why is it that the errors don't stop the library build? Is there something fundamentally different about these scenarios that causes make to behave differently?
I'm fairly new to c++ (and to compiled languages generally)--I imagine there is something fundamental about the build process that I'm not understanding. I found it difficult to search for this--searching for "c++ library build no error" gives me a lot of threads on c++ library build errors.
In general, libraries are simply collections of compiled code - object files. As a rule the linkage errors that you're seeing will only be picked up when you create an executable at which point the linker will try to ensure that all symbols used in your executable can be resolved with the libraries that you're linking against.
If the definition of a symbol (function, constant etc) either cannot be found or is ambiguous (i.e. can be found in more than one place, then linking will fail.
While linking, it checks for cross-references, symbols (functions, identifiers etc) definition and call or use gets binded in static linking (dynamic linking is different where cross-referencing may not be done as this is deferred linking). Library is a simple collection of function or identification definition, doesn't do cross-referencing.

How I do compile a application against a static library compiled with libc++ in xcode/clang/macos?

When I try to compile a test console application to test some functionality on a static library on the same workspace, i run into problems in the linking stage of the binary, it only happen when I choose to use libc++ standard library.
The missing symbols error is the follow :
Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::empty() const", referenced from:
libtorrent::torrent::replace_trackers(std::__1::vector<libtorrent::announce_entry, std::__1::allocator<libtorrent::announce_entry> > const&) in libLibOFFTorrent-xcode.a(torrent.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
When I choose stdlibc++ in both targets everything compiles ok and it runs OK.
my questions are :
there are some restriction on using libc++ on static libraries?
its a bug in apple/clang++ linker tool?
how can I configure the project to use libc++ with my static
libraries?
why the linker tool does not find the symbols of a standard c++
libraries on a static lib?, (any other lib that depends on is compiled against libc++)
should I forget the idea on using libc++?
notes:
the static library depends on libboost_system, witch i had compiled with libc++ and libstdc++ with the same results
when i run the test with the 'bjam' tool it runs OK, maybe the jam files chooses libstdc++ to compile the files.
I know that changing the standard library fix the linking problem , I only want to know why is that.
UPDATE: when I remove the reference to string::empty in the static lib project, the project that depends on compiles with libc++ fine and runs, but it gets in a infinite loop.
UPDATE 2: removing the string::empty references causes no effect when I compile the whole thing with libstdc++ it runs fine. no loops, this makes me think that is a bug or something like that.
UPDATE 3: when it compiles this is the place where the programs loops indefinitely :
It seems that one of your dependencies (libtorrent) has been built against libstdc++.
Check the namespace : std::__1::basic_string. It has the __1 prefix, usually indicating libstdc++).
I may be wrong but I think you need to rebuild your libtorrent against libc++ if you absolutely want to use this one.
Note that it is pretty common to use the stdlibc++.
Did you by any chance compile libtorrent with a -D_LIBCPP_INLINE_VISIBILITY=""?
The reason I ask is that std::string::empty() isn't in libc++.dylib because it is marked up with "always_inline". And so it should have been inlined into libtorrent when it was used.

duplicate symbols when importing c++ file

I have a project in XCode that uses some C++ code (openCV to be exact). One of my files, AdjustVC.mm importing this file (it's called image_processing.mm). Everything works fine. But when I import image_processing.mm in another file, TestVC.mm, I get errors:
ld: 14 duplicate symbols for architecture armv7
It's not a problem about your code base, ld is the tool for the linking phase, most likely you are using your libraries in the wrong way.
you should add more details about the libraries involved in your project or just verify them.

Eclipse-CDT/C++: Undefined reference-errors although right .o-files are created and passed to the linker

At first: I am not using an already compiled library.
Here's the situation: I've got a C++ project in eclipse CDT that has a folder structure like this:
project
somefoldername
src
include
library
src
include
somefoldername/src and library/src are defined as source folders and somefoldername/include as well as library/include are defined as include folders (under C/C++ General->Paths and Symbols, which also affects the compilers -I option).
The "library" folder contains the source code of a library used by my own code (which can be found in "somefolder"). Well, compiling of the whole project works fine, but linking crashes with a whole bunch of "undefined reference" errors in the library's source.
The undefined reference errors occur, although *.o-files are created in which the missing functions should be found - and also are passed to the linker afterwards.
What am I doing wrong?
Edit: Updated to current configuration and the attempts to solve the problem.
Edit2: The accepted answer helped me out a bit, but the biggest problem seemed to be the "linking everything at once"-policy followed by eclipse. I went to autoconf and built the library first, before linking it to the main application. Although it's more work, it's a cleaner approach.
Three possibilities:
1) The "undefined" symbols aren't actually in your library
This is unlikely, but you can verify using the "nm" Linux command
2) You aren't setting the library search path ("dash-big-L") correctly in Eclipse
link static lib in eclipse cdt
... or ...
3) Perhaps you built the library with "C" linkage, but your program is using C++ linkage (or vice versa). If you're using the "C" (gcc") compiler, or have any "*.c" source files, then make sure all functions have prototypes in your .h header, and all prototypes use "extern "C"" as appropriate:
& http://msdn.microsoft.com/en-us/library/0603949d%28v=vs.80%29.aspx

g++ linking issues: undefined reference to functions

I used CMake and Visual C++ to build the HyDE library. Then, still in VC++, I was able to successfully create code and build an executable that links into HyDE.lib and the HyDE header files.
I then discovered that in order to work with others at my company, it would be preferable to develop in Eclipse CDT. Knowing very little about Eclipse CDT, I created a default hello world project, deleted the code and then dumped in all of my code into the src folder. Then I attempted to change the includes and lib path and libs to mirror what had worked in VC++. At this point everything seems to compile, but I get an error in linking:
/cygdrive/c/EclipseWorkspace/425HyDE/Debug/../src/FS5HyDE.cpp:16: undefined reference to `HyDEAPI::HyDE::HyDE(HyDESystemModel::SystemModel*, bool)'
(There are many more errors like this, all referring to HyDE methods.) Here is what is being run at the command line:
g++ -L"C:\Progra~1\boost\boost_1_42\lib" -L"C:\EclipseWorkspace\HyDE" -o"425HyDE.exe" ./src/Adapter_FS5HyDE.o ./src/EPSCommands.o ./src/EPSCurrentSensor.o ./src/EPSFault.o ./src/FS5HyDE.o ./src/HyDEObservation.o ./src/MCDH.o ./src/MCDH_Module.o ./src/PDBComponent.o ./src/PowerSystem.o ./src/Program.o ./src/SSPCComponent.o ./src/Telemetry.o ./src/TelemetryReport.o -l:libboost_thread-vc90-mt-gd-1_42.lib -lHyDE
This is definitely not a library ordering problem because I've the other ordering as well (there are only two). Is it possible that there is a problem with compiling HyDE.lib in VC++ (which uses a Windows compiler) and compiling my program with g++? Could there be a problem in the way that Eclipse CDT is autogen'ing the makefiles? Any other ideas?
(Note: there appear to be plenty of others questions on SO with similar problems, but after reading through them I have yet to find one that addresses my problem.)
Classic missing symbol error. Which source file defines:
HyDEAPI::HyDE::HyDE(HyDESystemModel::SystemModel*, bool)' ?
Was this file added to the compilation? Can you spot it on the command line you pasted?
If this symbol belongs to an external library, after adding the directory path with -L , you could add the name of the specific library you want to link with your program using -l.
I'm going to suggest that you try to add to the compilation command the directory path to HyDE.lib, followed immediately by the library name, like this:
-L"C:\path_to_hyde_library" -l:HyDE.lib
and then tell us what happened.
Solution: Since the HyDE library was compiled with the Visual Studios compiler and I'm attempting to build the code that links to it with the Cygwin toolchain the two compilers use different name mangling schemes so that the latter linker can not find the expected symbols in the HyDE library. The only solution that I've found is to recompile the HyDE library with the Cygwin toolchain or compile the new code with whatever compiler Visual Studios is using. (grumble grumble)
./src/FS5HyDE.o and ./src/HyDEObservation.o should be the latest parameter if other object files (*.o files) need them, it means that the most needed object files should be appeared as last as possible in the parameters list.