CocoaPods: Linking with C++ symbols defined in libPods.a - cocoa

I recently started working on a podSpec file that integrates levelDB into my projects.
(https://github.com/iljaiwas/Podspecs/blob/master/LevelDBPodSpec/0.0.1/leveldb.podspec)
However, when I reference any C++ symbol from a .mm file in the main target, I get a linker error like this:
Undefined symbols for architecture x86_64:
"leveldb::DB::Open(leveldb::Options const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::DB**)", referenced from:
-[IHLevelDBContext initWithPath:] in IHLevelDBContext.o
This is what the compiler invocation looks like
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk -L/Users/ilja/Library/Developer/Xcode/DerivedData/LevelDBTest2-aiflqgbevhxzfxbrsdamteybrbao/Build/Products/Debug -F/Users/ilja/Library/Developer/Xcode/DerivedData/LevelDBTest2-aiflqgbevhxzfxbrsdamteybrbao/Build/Products/Debug -filelist /Users/ilja/Library/Developer/Xcode/DerivedData/LevelDBTest2-aiflqgbevhxzfxbrsdamteybrbao/Build/Intermediates/LevelDBTest2.build/Debug/LevelDBTest2.build/Objects-normal/x86_64/LevelDBTest2.LinkFileList -mmacosx-version-min=10.7 -ObjC -fobjc-arc -fobjc-link-runtime -stdlib=libc++ -framework Cocoa -lPods -o /Users/ilja/Library/Developer/Xcode/DerivedData/LevelDBTest2-aiflqgbevhxzfxbrsdamteybrbao/Build/Products/Debug/LevelDBTest2.app/Contents/MacOS/LevelDBTest2
From my understanding, the missing ::Open call is included in libPods.a
nm libPods.a | grep "Open"
U __ZN7leveldb2DB4OpenERKNS_7OptionsERKSsPPS0_
000000000005e5b1 s L___func__._ZN7leveldb6DBImpl24OpenCompactionOutputFileEPNS0_15CompactionStateE
00000000000099d0 T __ZN7leveldb2DB4OpenERKNS_7OptionsERKSsPPS0_
0000000000060ba0 S __ZN7leveldb2DB4OpenERKNS_7OptionsERKSsPPS0_.eh
It seems I can get around the linker errors by changing the "Compiler" setting for the main app from Apple LLVM 4.2 to LLVM GCC 4.2, but this compiler chokes on Objective-C 2.0 features, like this:
expected a property attribute before 'strong'
Thanks for any pointers on what I might be doing wrong,
Ilja

You can also set the C++ config settings in the podspec file:
s.library = 'c++'
s.xcconfig = {
'CLANG_CXX_LANGUAGE_STANDARD' => 'c++11',
'CLANG_CXX_LIBRARY' => 'libc++'
}
Those settings selects to compile for C++ 2011 and adds the libc++ standard library.

The problem went away after I set the "C++ Standard Library" setting in both the application target and CocoaPods target to "compiler default". Seems they were set to incompatible values by default, which caused linker confusion afterwards.

Related

OpenCV 3.0.0 with Xcode 6.3

I'm trying to compile a simple opencv code using Xcode but I'm getting a compilation error.
The opencv version is 3.0.0 and Xcode version is 6.3 (OS X 10.10.3)
In Xcode, Apple LLVM 6.1 Language C++ settings are:
c++ Language Dialect : C++11[-std=c++11]
c++ Standard Library : libc++
the error is:
Undefined symbols for architecture x86_64:
"cv::imread(cv::String const&, int)", referenced from:
_main 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)
When I change the c++ standard library to libstdc++, then the error was:
/usr/local/include/opencv2/hal/defs.h:271:14: 'cstdint' file not found
Can someone show me how to get opencv work with Xcode? I've already followed lot of forums and guides but still getting the same error.
I had the same problem, either I got the "Undefined symbols x86_64" with libc++, or "cstdint file not found" with libstdc++.
What finally made it work for me was that I needed to add a lot more libs than I'm used to, it wasn't enough to add just core, imgproc, and highgui for even a simple project.
So I went to Build Settings, searched for Linking, and in Other Linker Flags I added the whole lot:
-lopencv_calib3d -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videoio -lopencv_videostab
I'm using OpenCV 3.0.0 and Xcode 6.4. C++ Standard Library set to libc++ and C++ Language Dialect C++11. Hope this helps!

Undefined Symbols when linking project with GLFW3 using CMake on OSX

I am following this guide on how to build a project using GLFW3 with CMake on OSX 10.9.1, and I've run into some trouble. When I get to building the actual project I get the following errors:
$ make
Scanning dependencies of target Graphics
[100%] Building CXX object CMakeFiles/Graphics.dir/graphics.cpp.o
Linking CXX executable Graphics
Undefined symbols for architecture x86_64:
"_glBegin", referenced from:
_main in graphics.cpp.o
"_glClear", referenced from:
_main in graphics.cpp.o
"_glColor3f", referenced from:
_main in graphics.cpp.o
"_glEnd", referenced from:
_main in graphics.cpp.o
"_glLoadIdentity", referenced from:
_main in graphics.cpp.o
"_glMatrixMode", referenced from:
_main in graphics.cpp.o
"_glOrtho", referenced from:
_main in graphics.cpp.o
"_glRotatef", referenced from:
_main in graphics.cpp.o
"_glVertex3f", referenced from:
_main in graphics.cpp.o
"_glViewport", referenced from:
_main in graphics.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[2]: *** [Graphics] Error 1
make[1]: *** [CMakeFiles/Graphics.dir/all] Error 2
make: *** [all] Error 2
My CMakeLists.txt looks like:
cmake_minimum_required (VERSION 2.8)
project (Graphics)
# The version number.
set (Graphics_VERSION_MAJOR 1)
set (Graphics_VERSION_MINOR 0)
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/GraphicsConfig.h.in"
"${PROJECT_BINARY_DIR}/GraphicsConfig.h"
)
# add the binary tree to the search path for include files
# so that we will find GraphicsConfig.h
include_directories("${PROJECT_BINARY_DIR}")
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
include_directories(${GLFW_INCLUDE_DIRS})
# add the executable
add_executable (Graphics graphics.cpp)
target_link_libraries(Graphics ${GLFW_STATIC_LIBRARIES})
# add the install targets
install (TARGETS Graphics DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/GraphicsConfig.h"
DESTINATION include)
However can build the project just fine using
cc `pkg-config --cflags glfw3` -o graphics graphics.cpp \
`pkg-config --static --libs glfw3`
I can't offer you an explanation for why one links with the OpenGL libs and the other doesn't, but the following solution worked for me with a similar problem on OSX (Mountain Lion).
At the end of the 'add executable' block, add an Apple-specific condition to link with the OpenGL framework:
# add the executable
add_executable (Graphics graphics.cpp)
target_link_libraries(Graphics ${GLFW_STATIC_LIBRARIES})
if (APPLE)
target_link_libraries(Graphics "-framework OpenGL")
endif()
I figured there must be something in the GLFW CMake config that was responsible for linking with the OpenGL libs so I had a look at the GLFW 3.0.4 CMakeLists.txt and found that '-framework' line.
This will only help you on OSX - you'd need to supply other platform specific ways of linking to make it cross platform.
You may have already considered it, but the same guide also provides a way to include the GLFW source with your app and build it that way. That's probably the easiest way to guarantee cross-platform compatibility.
I had to do this.
elseif(APPLE)
# GLFW
find_package(glfw3 REQUIRED)
include_directories(${GLFW_INCLUDE_DIRS})
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
# app_framework executable
add_executable(app_framework ${SOURCE_FILES})
target_link_libraries(app_framework app_framework_library ${GLEW_LIBRARY} glfw3)
target_link_libraries(app_framework "-framework OpenGL")
Note that I use "glfw3" instead of ${GLFW_STATIC_LIBRARIES} in target_link_library. Did not work for me otherwise.
I'm using cmake 3.6.1.
Add this to your CMakeFile,
add_executable(${LOCAL_PROJECT_NAME} )
#openGL Specific
target_link_libraries(${LOCAL_PROJECT_NAME} ${GLFW_STATIC_LIBRARIES})
find_package(glfw3 3.3 REQUIRED)
target_link_libraries(${LOCAL_PROJECT_NAME} glfw)
find_package(OpenGL REQUIRED)
target_link_libraries(${LOCAL_PROJECT_NAME} OpenGL::GL)
also, make sure compiler options are set accordingly.

Linking protocol buffers library in XCode

I want to use Google Protocol Buffers for C++ in XCode.
This is my directory where I have the library: /Developer/Protobuf.
What I did inside this directory, is compiled the .proto and produced the .pb.h & .pb.cc files. After this produced the object file:
clang++ -arch x86_64 -I./src -I./ -c file.pb.cc
Then:
ar -r file.pb.a file.pb.o
In XCode, in Build Phases -> Link Binary With Libraries I have added file.pb.a static library. In Build Settings -> Header Search Paths I have added /Developer/Protobuf/src. In Build Settings -> Librabry Search Paths I have added /Developer/Protobuf. In Build Settings -> User Header Search Paths I have added also /Developer/Protobuf/src.
But when I compiled the project I always get this kind of errors:
Undefined symbols for architecture x86_64:
"google::protobuf::DescriptorPool::generated_pool()", referenced from:
musicbrainz::protobuf_AssignDesc_musicbrainz_2eproto() in musicbrainz.pb.o
"google::protobuf::DescriptorPool::InternalAddGeneratedFile(void const*, int)", referenced from:
musicbrainz::protobuf_AddDesc_musicbrainz_2eproto() in musicbrainz.pb.o
"google::protobuf::MessageFactory::generated_factory()", referenced from:
musicbrainz::protobuf_AssignDesc_musicbrainz_2eproto() in musicbrainz.pb.o
"google::protobuf::MessageFactory::InternalRegisterGeneratedFile(char const*, void (*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&))", referenced from:
musicbrainz::protobuf_AddDesc_musicbrainz_2eproto() in musicbrainz.pb.o
.................................................................................
Maybe I am not creating the static library correct ?
First of all, you need to compile the Protocol Buffers static libraries using their makefiles, and then, link in the static libraries into your project. You should not be pulling in their source code into your Xcode project.
When linking the libraries into my project, I had the same 'undefined symbols' errors as you. Based on comment #19 in this discussion, running the following commands when building the Protocol Buffers libraries will make them go away.
$ ./configure CC=clang CXX="clang++ -std=c++11 -stdlib=libc++" CXXFLAGS="-O3" --disable-shared
$ make

imwrite throwing compile error in OpenCV

I have been using OpenCV for a while and also the imwrite function, but unfortunately this is not working any more.
I am running with OpenCV 2.4.3 with following sample code:
imwrite("somepath/somefile.png", myMat);
The error:
Undefined symbols for architecture x86_64:
"cv::imwrite(std::string const&, cv::_InputArray const&, std::__debug::vector<int, std::allocator<int> > const&)", referenced from:
MyProject::this_callback(int, void*) in MyProject.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The error looks somewhat familiar but i cannot determine whats wrong.
Yes, I've thought you were using XCode. I had the same problem. :)
If you change the project setup so that:
you use GNU++11 as C++ language dialect
libstdc++ (GNU C++ standard) as C++ standard library
your linking problem will go away.
I use Apple LLVM 4.1.
When I had this problem, I have tried just adding a new target to one of my old projects I knew, worked. Then I've just made that target a one-source-file program.
This must be a "magic" part of XCode as I think there was a time I could not get the same project working after a restart. :S
I did what Barnabas did and also got the issue on cvdef.h. I was getting desperate so and what I did was just changed the header file.
in /usr/local/cvdef.h line 205:
I changed
include <cstdint>
typedef std::uint32_t uint;
to:
include <tr1/cstdint>
typedef std::tr1::uint32_t uint;
based on this post
I think opencv devs should apply some changes to the code for 64bit..
use something like clang version 3.8.0 (trunk 257459), instead of gcc version 4.9.2 (MacPorts gcc49 4.9.2_1+universal) to compile
for reference, cmd: clang++ -std=c++11 `pkg-config --cflags --libs opencv` code.cpp -o code

xcode 3.0 - file is not of required architecture

I am using Xcode 3.0 to compile a test C program using CFITSIO library.
Following advice I have encountered from previous posts, I have built CFITSIO as a universal library, and added the fitsio.h and libcfitsio.a files to my project. I have verified I am using the correct build (x86_64). I have verified the libcfitsio.a file is under the Target > Link Binary with Libraries tab. I continue to receive the following error.
A previously created project using cfitsio works - I wasn't the one to link the library.
Also, I can link cfitsio successfully from terminal.
Any suggestions?
Building target “test1” of project “test1” with configuration “Release”
Checking Dependencies
ld /Users/jacqueline/test1/build/test1.build/Release/test1.build/Objects-normal/ppc/test1 normal ppc
cd /Users/jacqueline/test1
/Developer/usr/bin/gcc-4.0 -o /Users/jacqueline/test1/build/test1.build/Release/test1.build/Objects-normal/ppc/test1 -L/Users/jacqueline/test1/build/Release -L/Users/jacqueline/test1 -L/Users/jacqueline/test1/cfitsio/build/i386 -L/Users/jacqueline/test1/cfitsio/build/ppc -L/Users/jacqueline/test1/cfitsio/build/x86_64 -L/Users/jacqueline/test1/cfitsio/lib -L/Users/jacqueline/test1/cfitsio -F/Users/jacqueline/test1/build/Release -filelist /Users/jacqueline/test1/build/test1.build/Release/test1.build/Objects-normal/ppc/test1.LinkFileList -lcfitsio -arch ppc -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk
ld: warning in /Users/jacqueline/test1/libcfitsio.a, file is not of required architecture
Undefined symbols:
"_ffopentest", referenced from:
_main in main.o
"_ffclos", referenced from:
_main in main.o
"_ffgrec", referenced from:
_main in main.o
"_ffghsp", referenced from:
_main in main.o
"_ffrprt", referenced from:
_main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
It seems as though the library is not fully universal. Try building your project for just one of the architectures at a time (i.e., just ppc, ppc64, i386, and x86-64 separately). When (if) one of them fails, you know which architecture your library is missing so you can recompile it with that. (Or, alternatively, if you don't intend to deploy on that architecture, you can just not compile for it. For instance, there's no real point in building PPC 64 unless you really will benefit from it, as the only machines that will run it are G5s, and they'll run plain old PPC 32-bit code just fine.)
Once I edited Xcode
'Project' > 'Edit Project Settings' > 'Architecture'
to not include PPC, which seemed to be there by default, the build succeeded. I am running OSX 10.5.8 on Intel Core 2 Duo.
Previously I had been using various builds of the cfitsio library itself, and not changing the default architecture on my Xcode project.

Resources