using c++ static library in objective c - c++

I have a static library, whose code was in c++. I want to use it in an objective C app.
(I have been using C libraries preiously, they have been working fine.)
I added the library and tried to build, it couldn't because 'namespace' and vectors were somewhere used in the header files. So, I had to change the type of my objective C file to objective c++. (I didn't change the extension to .mm). Since this file was to be included in another file, that file also had to be changed to c++, similarly for few other files.
Now there is no namespace error. But now when I build, it cribbs that it can't find the referenced symbols. I now changed the extension to .mm, still the same.
I did some searching, I read some things about mangling. I don't understand what that is, but here is something i tried,
Instead of calling the c++ function directly, I created a C function, whose declaration was preceded by 'extern "C"', and the library call was present in this C function. Still the same. I preceded the implementation of the c function by 'extern "C"', still the same.
I also read that if xcode sees .mm extension, only then it uses g++ compiler. and in that case there is no need for extern "C". is it?
Do I need to add some compiler flags in the Other compiler flags target setting?
ld: warning: directory not found for option '-F-F/Users/username/Desktop/projectFolder'
Undefined symbols for architecture armv7:
"IIS::Image::Image::Image(unsigned int, unsigned int, ImageFormat)", referenced from:
-[ImageEditorSupport loadToolKitForImage:width:height:length:] in ImageEditorSupport.o
"IIS::Image::Image::getNumComponents(unsigned int&) const", referenced from:
-[ImageEditorSupport loadToolKitForImage:width:height:length:] in ImageEditorSupport.o
"IIS::Image::ToolKit::adjustSaturation(IIS::Image::Image const&, unsigned int, IIS::Image::Image&)", referenced from:
-[ImageEditorSupport applyToolkitForEditID:intensity:] in ImageEditorSupport.o
"IIS::Image::ToolKit::adjustContrast(IIS::Image::Image const&, unsigned int, IIS::Image::Image&)", referenced from:
-[ImageEditorSupport applyToolkitForEditID:intensity:] in ImageEditorSupport.o
"IIS::Image::Image::Image(unsigned int, unsigned int, ImageFormat, void*, unsigned int)", referenced from:
_create_image_using_buffer in ImageEditorSupport.o
"IIS::Image::ToolKit::adjustColorTemp(IIS::Image::Image const&, int, IIS::Image::Image&)", referenced from:
-[ImageEditorSupport applyToolkitForEditID:intensity:] in ImageEditorSupport.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have also checked several times that i have added the correct library search paths.
I am doubtful about the two '-F-F'. I was expecting only one.
*Edit :*In the warning -F-F/Users/username/Desktop/projectFolder does it mean that it is searching for a path -F/Users/username/Desktop/projectFolder instead of /Users/username/Desktop/projectFolder ? How could that extra -F come?

Seems it hasn't been compiled for armv7 architecture.
You can check with lipo -info myLib.a

The UIViewController in which you're using that c++ library should have the extension .mm instead .m (thats default). Also your main.m should now main.mm
This is because you're using c++ code in Objective-c.

Related

Having problem adding Firebase to my C++ project

So I was trying to use C++ Firebase API to store data from my C++ application to google cloud (firebase). That is my whole purpose.
I have written the necessary code for it based on my understanding from this website: https://firebase.google.com/docs/database/cpp/start and this website: https://firebase.google.com/docs/cpp/setup
These websites give you some sort of how can you add firebase API to my C++ application. The header files or Firebase SDK are from the second website.
So I am using iMac and Visual Studio and I tried to run my code but I got these errors:
././include/firebase/./database/database_reference.h:107:25: warning: 'override' keyword is a C++11 extension [-Wc++11-extensions]
bool is_valid() const override;
^
1 warning generated.
Undefined symbols for architecture x86_64:
"firebase::App::Create(firebase::AppOptions const&)", referenced from:
_main in test-1dd10f.o
"firebase::Variant::Clear(firebase::Variant::Type)", referenced from:
firebase::Variant::set_int64_value(long long) in test-1dd10f.o
firebase::Variant::~Variant() in test-1dd10f.o
"firebase::database::DatabaseReference::SetValue(firebase::Variant)", referenced from:
_main in test-1dd10f.o
"firebase::database::DatabaseReference::~DatabaseReference()", referenced from:
_main in test-1dd10f.o
"firebase::database::Database::GetInstance(firebase::App*, firebase::InitResult*)", referenced from:
_main in test-1dd10f.o
"firebase::database::DatabaseReference::Child(char const*) const", referenced from:
_main in test-1dd10f.o
"firebase::database::Database::GetReference(char const*) const", referenced from:
_main in test-1dd10f.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Incidentally, I had to change some paths of some header files because somehow, when I compile the file, I get an error of "file not found". I mean I believe I am not suppose to change the original path from firebase header files or SDK to what ever I want (maybe I am wrong).
For example, if I have my myapp.cpp file in the same directory as the firebase folder which has all the headers files, I can just add the header file app.h like this #include "firebase/app.h". But some of these header files include other header files which as the following "#include firebase/internal/common.h" and that caused a file not found error for me. So, I had to change these header files path to something like that "#include "../internal/common.h". I don't think this is an issue as well.
I don't have much knowledge of C++. But I think this is an environment issue and I don't know what to do.
I did not follow the steps about Pod (in the website) because I don't know if that is necessary or I don't understand the instructions clearly.
#include <iostream>
#include "./include/firebase/app.h"
#include "./include/firebase/database.h"
using namespace std;
using namespace firebase;
using namespace database;
int main () {
::firebase::AppOptions appOptions = ::firebase::AppOptions();
appOptions.set_api_key("AIzaSyDocIMJCv9ZfPq8ozvkeSc5PlC-X5gW5_k");
appOptions.set_app_id("smarttrafficmonitoring.firebaseapp.com");
appOptions.set_database_url("https://smarttrafficmonitoring.firebaseio.com");
appOptions.set_project_id("smarttrafficmonitoring");
appOptions.set_storage_bucket("smarttrafficmonitoring.appspot.com");
appOptions.set_messaging_sender_id("220108272524");
::firebase::App* app;
app = ::firebase::App::Create(appOptions);
::firebase::database::Database *database = ::firebase::database::Database::GetInstance(app);
firebase::database::DatabaseReference dbref = database->GetReference("intersections");
dbref.Child("intersection").Child("NSLane").Child("mid").SetValue(11);
cout << "It worked";
return 0;
}
For a darwin (macOS) target, you shouldn't need to use cocoapods. Pulling the latest C++ SDK in VSCode, I was able to build your example on my mac. My CMakeLists.txt file (I assume that this is how your project is being setup if you're not using XCode) is:
cmake_minimum_required(VERSION 3.1)
project(test_project)
set(FIREBASE_CPP_SDK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/firebase_cpp_sdk)
add_subdirectory(firebase_cpp_sdk)
add_executable(test_project main.cpp)
target_link_libraries(test_project firebase_app firebase_database)
main.cpp is the file you provided. I put the firebase c++ sources in a directory named firebase_cpp_sdk. I also made a minor change in how you import your headers:
#include <iostream>
#include <firebase/app.h>
#include <firebase/database.h>
Which is specific to how I setup my CMakeLists.txt file.
Important notes that may help:
I was getting linker errors with just add_subdirectory, the set for FIREBASE_CPP_SDK_DIR works around those by making sure I have a proper absolute path for the Firebase CMakeLists.txt file.
In target_link_libraries I make sure to link firebase_app in addition to firebase_database. Without these I get similar linker errors to your own. As for which libraries to link, I referenced the open source repository here:
https://github.com/firebase/firebase-cpp-sdk
One additional note: if you are linking the libraries manually (ie: not via CMake's systems), I noticed that your linker errors specifically reference the x86_64 architecture. CMake seems to prefer the .a files in libs/darwin/universal, so I would try that first, but you can also try the /libs/darwin/x86_64 directory to see if that helps at all.
Hopefully this gets you unstuck!
One final note is that the desktop SDK support is pretty beta, if you do run into bugs after you get setup, feel free to file them on the GitHub bug tracker:
https://github.com/firebase/firebase-cpp-sdk/issues
I hope that all helps.

How can I resolve single symbol link error when dynamically linking XCode project to lib4cxx library?

I'm writing in C++ under XCode 4.6 on Mountain Lion. I'm trying to add and use the Apache log4cxx library. I installed the library this morning via Brew. I'm linking against liblog4cxx.dylib. I'm getting a link error that just one symbol can't be found:
Undefined symbols for architecture x86_64:
"log4cxx::Logger::forcedLog(log4cxx::helpers::ObjectPtrT
const&, std::__1::basic_string,
std::__1::allocator > const&, log4cxx::spi::LocationInfo const&)
const", referenced from:
I know it's finding the library file because if I remove it, I get lots more undefined symbol errors relating to log4cxx.
relevant code is basically:
#include <log4cxx/logger.h>
static LoggerPtr logger(log4cxx::Logger::getLogger("foo.bar.Baz"));
void foo(int p1, int p2)
{
LOG4CXX_WARN(logger, "blah blah blah");
}
Creating the logger object inside the function, either as static or not, doesn't change the behavior. Also, linking with the static library, with or without defining LOG4CXX_STATIC in my project, does not change the behavior.
Looking at the macro I'm calling, I see that this symbol is the actual method that performs the log operation. If take out the logging call but leave in the code that defines the logger object, the code links fine as you might expect.
What do I need to do to have this last symbol resolve?
TIA!
I traced my issue down to compiling the library in a non C++11 compiler, but then my target project was a C++11 compiler.
I was able to compile log4cxx in a C+11 compiler by viewing the changes to log4cxx in the development git repo, which mainly consisted of inserting static_casts, as in this update:
http://apache-logging.6191.n7.nabble.com/C-11-does-not-allow-char-literals-with-highest-bit-set-unless-cast-td34908.html
I suppose the few incompatible routines came up undefined, which is why we were getting confused with only a few seemingly random undefines. (Or I was anyway)

Linking Error with UnitTest++

I am getting an odd Unit Test ++ linking error using Xcode as my ide.
Now I did set the project up with two targets. one target that will do the test the other will do nothing for now.
Note I did link the library and ran the simple working example from the tutorial.
and I compiled it using gcc 4.2.1 from macports.
"std::string::c_str() const", referenced from:
UnitTest::MemoryOutStream::GetText() const in libUnitTest++.a(MemoryOutStream.o)
"std::basic_ostringstream, std::allocator >::str() const", referenced from:
UnitTest::MemoryOutStream::GetText() const in libUnitTest++.a(MemoryOutStream.o)
"std::basic_ostream >::~basic_ostream()", referenced from:
construction vtable for std::ostream-in-UnitTest::MemoryOutStream in libUnitTest++.a(TestRunner.o)
construction vtable for std::ostream-in-UnitTest::MemoryOutStream in libUnitTest++.a(Test.o)
"std::basic_ostream >::~basic_ostream()", referenced from:
construction vtable for std::ostream-in-UnitTest::MemoryOutStream in libUnitTest++.a(TestRunner.o)
construction vtable for std::ostream-in-UnitTest::MemoryOutStream in libUnitTest++.a(Test.o)
Okay so all the problems went away when I switched the std library to GNU standard library rather then the llvm osx standard library. So go to build settings c++ standard library libstdc++ (GNU C++ standard library)

Building static C++ lib for use with Objective-c app in Xcode 4

I found examples and posts to
Create a static C++ lib for use in a C++ application
Create a static Objective C lib for use in an Objective C app.
What I couldn't find and have hassled around with for days now, is the correct way to create a static C++ lib for use in a Objective-C app under XCode 4.
I just want to use this very simple code for testing purposes:
#include <iostream>
#include "myCppLib.h"
using namespace std;
extern "C" void show_the_world() {
cout << "Hello, world!\n";
}
I compile this with armv6/armv7 target, GCC 4.2 compiler, Linking 'C++ Standard Library Type' as 'Static' and have "Symbols Hidden by Default" to YES, as described by the Xcode help for static C++ libs.
My Objective-C app which calls the 'show_the_world' function errors about the std++ lib, which seems not to be included or not correctly referenced:
Undefined symbols for architecture armv6:
"std::ios_base::Init::~Init()", referenced from:
___tcf_0 in libmyCppLib_dev.a(myCppLib.o)
"std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from:
_show_the_world in libmyCppLib_dev.a(myCppLib.o)
"std::ios_base::Init::Init()", referenced from:
__static_initialization_and_destruction_0(int, int)in libmyCppLib_dev.a(myCppLib.o)
"std::cout", referenced from:
_show_the_world in libmyCppLib_dev.a(myCppLib.o)
ld: symbol(s) not found for architecture armv6
collect2: ld returned 1 exit status
I am sure that I compiled the library for the right architecture, so there must be something wrong in another setting or with my code.
Any help is welcome!
Best regards,
jimmy
The correct answer was provided by Jimmy Koerting in the comments: the app needs to be linked against libstdc++.dylib to resolve the standard library symbols.
Thanks to Jimmy Koerting, but one more thing i want to add here is, if you are using xcode latest version with iOS 6.1 please add this libstdc++.6.dylib
Answered in my own comment ;)
the point was to include the std++ lib into the compiling of the resulting objective-c project, too.

XCode importing C++ project problems: "referenced from"

I have some problems importing an existing C++ project into my XCode. I already resolved some issues on includes (the use of string.h from another library was a pain), and now I stumbled upon another problem.
When I build the project, I have 35 errors, all of the same origin.
For example:
"_EVP_DigestInit_ex", referenced from:
getParameterBdd(char*, char*, char*, char*, int)in main.o
and
"wxStringBase::InitWith(wchar_t const*, unsigned long, unsigned long)", referenced from:
wxStringBase::wxStringBase(wchar_t const*)in main.o
It just goes on and on like this, for almost every function I can find in my own code.
I must have forgotten something obvious, but I've found nothing on any forum that can help me.
Thanks in advance!
These are linker errors; you can tell that from the fact that .o files are being processed. That means compilation must have succeeded to produce these.
Did you specify all the right libraries? By the looks of it, you need to link with at least OpenSSL (-lssl -lcrypto -lz) and wxWidgets.