OpenCV Unresolved symbols - name mangling mismatch - xcode - xcode

I built the i386 flavor of OpenCV locally on my Macbook running Lion, by using
cmake -G "Unix Makefiles" -D CMAKE_OSX_ARCHITECTURES=i386 -D CMAKE_C_FLAGS=-m32 -D CMAKE_CXX_FLAGS=-m32 ..
make -j8
sudo make install
Libraries built and published fine, and I've added them to my xcode project.
However, there are link errors when building my test app, and they seem to be name mangling issues.
Undefined symbols for architecture i386:
"cv::namedWindow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
_main in main.o
"cv::imread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
_main in main.o
"cv::imshow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::_InputArray const&)", referenced from:
_main in main.o
Taking cv::imread as an example, it is exported from libopencv_highgui.dylib with the name:
00007510 (__TEXT,__text) external __ZN2cv6imreadERKSsi
while main.o is referencing the symbol
U __ZN2cv6imreadERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEi
On the other hand, function __ZN2cv7waitKeyEi from the same dylib links fine.
Both the test app and the framework are for i386 arch.
Any ideas what might be causing this issue?

I've had the same problem. I think the issue could be that if you have used the MacPorts to compile your OpenCV libraries, they probably got built by the GCC according to it's Portfile. I switched the compiler used in the XCode (Apple LLVM 4.1) to the LLVM GCC 4.2 and now it works.
Hope it helps.

I just had the same problem and fixed it by using libstdc++ as the C++ standard library. It was defaulted to libc++
Under Project Build settings -> APPLE LLVM compiler 4.2 - Language -> C++ Standard Library

Related

Linking against the correct libc++ with Xcode 9.0

I have a library that is written in a mixture of Fortran and C++. It also uses MPI at the Fortran layer. Let's say a user wants to link a new c++ program against my library. From what I've found on the internet, the best way to do this is to have them compile their code with a C++ compiler, and link against my library using the mpif90 fortran wrapper. This is to make sure you link against the correct version of MPI. But in order to make this all work, you also have to link against libc++ explicitly because otherwise your c++ program won't work. So, for example:
mpic++ their_code.cc -c
mpif90 their_code.o -o program.exe -lmylib -lstdc++
This approach has worked fine for me across many platforms and compilers (gnu, intel, etc). It also worked for clang, until the release of Xcode 9.0, which broke this process. The compiler errors appear to be related to incompatibility in the c++ standard library, because it only breaks when I call functions that pass std::string. In the Xcode release notes it says:
Projects created using this Xcode release use the new libc++ implementation of the standard C++ library. The libc++ library is available only on iOS 5.0 and later and OS X 10.7 and later. 12221787
To enable deployment on earlier releases of iOS and OS X in your project, set the C++ Standard Library build setting to libstdc++ (Gnu C++ standard library).
This leads me to believe I need to modify how I link against libc++. You can reproduce this issue with the following code (assuming you have upgraded Xcode to version 9).
main.cc:
#include<string>
using namespace std;
void fun_str(string s);
void fun_num(int n);
int main() {
string my_str = "test";
int my_num = 1;
fun_str(my_str);
fun_num(my_num);
return 0;
}
fun.cc:
#include <string>
using namespace std;
void fun_str(string s) {}
void fun_num(int n) {}
Makefile:
test: main.o fun.o
mpif90 main.o fun.o -o program.exe -lstdc++
main.o: main.cc
mpic++ main.cc -c
fun.o: fun.cc
mpic++ fun.cc -c
Notice how if you remove all the references to strings, it does compile correctly. But if not, you get the following error:
mpic++ main.cc -c
mpic++ fun.cc -c
mpif90 main.o fun.o -o program.exe -lstdc++
Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long)", referenced from:
_main in main.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
_main in main.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [test] Error 1
Additionally, if you switch to GNU by setting the environment variable OMPI_CXX to g++-7, it also compiles without a hitch. So this is definitely just a Clang issue, that only showed up in the new version. Any help would be greatly appreciated :)!
I fixed this on my own, but using -lc++ instead of -lstdc++. It seems that libstdc++ is depreciated with clang.

Unable to build electron 1.6.2 on OSX

I build the electron app with following scripts:
script/bootstrap.py -v --target_arch x64
script/create-dist.py
The first one ends successfully, but the second one throws this error (from TeamCity log):
...skipped log entries
[02:56:38][Step 2/2]
[1315/1328] SOLINK "Electron Framework.framework/Versions/A/Electron Framework", POSTBUILDS
[02:56:38][Step 2/2]
FAILED: ../../vendor/llvm-build/Release+Asserts/bin/clang++ -shared -ObjC -stdlib=libc++ -Wl,-dead_strip -mmacosx-version-min=10.9 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -arch x86_64 -L. -install_name #rpath/Electron\ Framework.framework/Electron\ Framework -Wl,-rpath,#loader_path/Libraries -F/Users/teamcity/buildAgent/work/e4f0eac9e33806e2/external_binaries -stdlib=libc++ -o "Electron Framework.framework/Versions/A/Electron Framework" #Electron_Framework.framework.rsp
[02:56:38][Step 2/2]
ld: warning: ignoring file /Users/teamcity/buildAgent/work/e4f0eac9e33806e2/vendor/brightray/vendor/download/libchromiumcontent/static_library/libwebkit.a, file was built for archive which is not the architecture being linked (x86_64): /Users/teamcity/buildAgent/work/e4f0eac9e33806e2/vendor/brightray/vendor/download/libchromiumcontent/static_library/libwebkit.a
[02:56:38][Step 2/2]
Undefined symbols for architecture x86_64:
"blink::WebCryptoKeyAlgorithm::createRsaHashed(blink::WebCryptoAlgorithmId,
unsigned int, unsigned char const*, unsigned int, blink::WebCryptoAlgorithmId)",
referenced from:
webcrypto::(anonymous namespace)::CreateRsaHashedKeyAlgorithm(
blink::WebCryptoAlgorithmId, blink::WebCryptoAlgorithmId, evp_pkey_st*,
blink::WebCryptoKeyAlgorithm*) in libcomponents.a(rsa.o)
"blink::WebCryptoAlgorithm::rsaHashedImportParams() const", referenced from:
webcrypto::RsaHashedAlgorithm::ImportKeyPkcs8(webcrypto::CryptoData const&,
blink::WebCryptoAlgorithm const&, bool, int, blink::WebCryptoKey*) const
in libcomponents.a(rsa.o)
skipped log entries...
It looks like the library and build machine are not compatible, but both of them are x64 platforms. What else can be wrong? I put here only part of the log, because it's really very long (thousands of lines). I used to use the same steps for building 1.2.3, 1.2.8 and 1.4.3 versions and there was no problem.
Try setting the ur valid architectures in xcode..

gmp-chudnovsky.c and xcode 4.5

when I try to compile and run the gmp-chudnovsky.c file found here with xcode the following errors appear:
Undefined symbols for architecture x86_64:
"_fac_clear", referenced from:
_main in main.o
"_fac_compact", referenced from:
_fac_remove_gcd in main.o
"_fac_init", referenced from:
_main in main.o
"_fac_mul", referenced from:
_bs in main.o
"_fac_mul_bp", referenced from:
_bs in main.o
"_fac_resize", referenced from:
_fac_remove_gcd in main.o
"_fac_set_bp", referenced from:
_bs in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I know the gmp library is installed correctly as I have another xcode project linking to it that is compiling correctly. Any ideas as to why this is happening?
Forgot to say I have added paths to the header file and library for GMP as well as add the -lgmp flag under Other Linker Flags
SOLVED: see this answer.
I think xcode runs in a Debug configuration first, where no optimization is performed and no inlining is carried out. This means any inline function must also be made static.

Awesomium on Mac OS X

Have anyone used to do with Awesomium framework on Mac OSX? I try to create a sample project and add code in main.m, but it has error
Undefined symbols for architecture i386:
"Awesomium::WebCoreConfig::setCustomCSS(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
_main in main.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Do you have any ideas for this error?
main.m is an Objective-C source file and std::__1::basic_string, std::__1::allocator > const& is a C++ class.
Change the name of main.m to main.mm, making it a Objective-C++ source file and try again.
Awesomium is 32 bit only (a current limitation of chromium) while Apple's compiler defaults to 64 bits these days.
You have to compile your app using -m32 (or if using Xcode setting the architecture to 32 bit only as in the link the OP posted)
Example:
clang -m32 awe_test.cpp -o test -framework Awesomium -F$(DIR_WHERE_I_HAVE_AWESOMIUM) -I$(DIR_WHERE_I_HAVE_AWESOMIUM)

Using Crypto++ with clang

I'm attempting to get the following Crypto++ (C++ Class Library of Cryptographic Schemes) example to work on a iMac using clang++.
Example
SHA256 hash;
byte digest[ SHA256::DIGESTSIZE ];
hash.CalculateDigest( digest, (byte*) &value[ 0 ], value.size( ) );
HexEncoder encoder;
string result = String::empty;
encoder.Attach( new StringSink( result ) );
encoder.Put( digest, sizeof( digest ) );
encoder.MessageEnd( );
Build command
Apple clang version 2.1 (tags/Apple/clang-163.7.1) (based on LLVM 3.0svn)
Target: x86_64-apple-darwin11.4.0
Thread model: posix
"/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.7.4 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name checksum_impl.cpp -pic-level 2 -mdisable-fp-elim -relaxed-aliasing -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 123.2.1 -v -resource-dir /usr/bin/../lib/clang/2.1 -D framework_EXPORTS -I /Users/Ben/Dropbox/appon/build/../source -nostdinc++ -cxx-isystem /usr/include/c++/v1 -Wall -Wextra -Weffc++ -pedantic -std=c++0x -fdeprecated-macro -ferror-limit 19 -fmessage-length 175 -stack-protector 1 -fblocks -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o CMakeFiles/framework.dir/Users/Ben/Dropbox/source/example.cpp.o -x c++ /Users/Ben/Dropbox/source/example.cpp
clang -cc1 version 2.1 based upon llvm 3.0svn hosted on x86_64-apple-darwin11.4.0
#include "..." search starts here:
#include <...> search starts here:
/Users/Ben/Dropbox/build/../source
/usr/include/c++/v1
/usr/local/include
/usr/bin/../lib/clang/2.1/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
Linker output
clang: warning: argument unused during compilation: '-std=c++0x'
Undefined symbols for architecture x86_64:
"CryptoPP::Filter::TransferTo2(CryptoPP::BufferedTransformation&, unsigned long long&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)", referenced from:
vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
"CryptoPP::Filter::CopyRangeTo2(CryptoPP::BufferedTransformation&, unsigned long long&, unsigned long long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) const", referenced from:
vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
"CryptoPP::BufferedTransformation::ChannelCreatePutSpace(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long&)", referenced from:
vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
"CryptoPP::BufferedTransformation::ChannelPut2(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned char const*, unsigned long, int, bool)", referenced from:
vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
"CryptoPP::BufferedTransformation::ChannelPutModifiable2(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned char*, unsigned long, int, bool)", referenced from:
vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
"CryptoPP::BufferedTransformation::ChannelFlush(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, int, bool)", referenced from:
vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
"CryptoPP::BufferedTransformation::ChannelMessageSeriesEnd(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int, bool)", referenced from:
vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
"CryptoPP::BufferedTransformation::SetRetrievalChannel(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
vtable for CryptoPP::SimpleProxyFilter in checksum_impl.cpp.o
vtable for CryptoPP::Bufferless<CryptoPP::Filter> in checksum_impl.cpp.o
vtable for CryptoPP::Unflushable<CryptoPP::Filter> in checksum_impl.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [all] Error 2
I'm using the latest development version of Crypto++ 5.6.2 as the previous version 5.6.1 fails to build with clang++. However i'm encountering build issues stating that i have missing symbols for x86_64 architecture.
Any hints would be greatly appreciated.
Crypto++ 5.6.2 successfully build on LLVM version 6.1.0 (clang-602.0.53) with make options:
CXXFLAGS="-std=c++11 -stdlib=libstdc++ -DCRYPTOPP_DISABLE_ASM -Wno-c++11-narrowing"
accordingly this script: https://github.com/mapnik/mapnik-packaging/blob/master/osx/scripts/build_cryptopp.sh
-stdlib=libstdc++ need for MacOSX since Mavericks, see: When is it necessary to use use the flag -stdlib=libstdc++?
you need to link to the library that provides those symbols, which should be libcryptopp.so, using-lcryptopp in the compiler command
Looking at your "build command" (which is not the command you're running, it's the output of the command you're running, it would be a lot easier to read if you showed the actual command) it seems you are compiling a .cpp file into a .o file, but getting a linker error, which is strange as producing a .o file is usualy the step before linking. What step are you trying to do? Maybe you also need to add -c so it only compiles and doesn't try to link. You will still need -lcryptopp when linking.
In addition to Jonathon's answer because this is a fairly prevalent problem when -lcryptopp is specified...
Undefined symbols for architecture x86_64. CryptoPP::Filter::TransferTo2(CryptoPP::BufferedTransformation&, unsigned long long&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)"...
The __1 indicates you are using the LLVM C++ runtime (libc++). Somewhere, you are probably mixing and matching with the GNU C++ runtime (libstdc++). The GNU C++ runtime (libstdc++) lacks the __1 decoration on its symbols.
You should go through the project and all pre-built libraries, and ensure they are using one or the other. For each, you should use CXXFLAGS of either (1) -stdlib=libc++ (LLVM), or (2) -stdlib=libstdc++ (GNU).
Be aware that IDEs like Xcode may use a different -stdlib=... setting than Crypto++. In this case, have Xcode match Crypto++, or rebuild the Crypto++ library to match Xcode.
If Xcode is using LLVM's libc++ and you have to rebuild Crypto++, then open the GNUmakefile and rework this section (around line 90):
ifeq ($(UNAME),Darwin)
AR = libtool
ARFLAGS = -static -o
CXX = c++
IS_GCC2 = $(shell $(CXX) -v 2>&1 | $(EGREP) -c gcc-932)
ifeq ($(IS_GCC2),1)
CXXFLAGS += -fno-coalesce-templates -fno-coalesce-static-vtables
LDLIBS += -lstdc++
LDFLAGS += -flat_namespace -undefined suppress -m
endif
endif
If you want to use LLVM's libc++, then remove:
# GNU C++ Runtime
LDLIBS += -lstdc++
And add:
# LLVM C++ Runtime
CXXFLAGS += -stdlib=libc++
For completeness, if you want to use GNU's runtime, then remove the LDLIBS += -lstdc++ and add CXXFLAGS += -stdlib=libstdc++.
You can also change CXX = c++ to CXX ?= c++ so the makefile will use c++ if its not specified in the environment or command line.
If interested, the __1 is an inline namespace used for versioning. See What are inline namespaces for? and Where does the __1 symbol come from when using LLVM's libc++?.
This issue was relating to Crypto++ not having been ported over to llvm-clang++. The supported compilers are listed on Platforms; supported compilers for previous releases are listed on Compiling.
My solution was to instead use GCrypt.
Sorry I can't supply anymore details on the cause of the failure.

Resources