How to build library written by C++ and use in iOS - c++

I now have to porting C++ code to iOS, trying to build static library by original C++ code and load the library on iOS. Because the original code is heavy, I start a small test to verify my steps could work or not.
First I need to build library (.a), which prints some string. I compile the following code and generate a library(.a) file
//talk.h
...
#include <iostream>
class Talk {
Talk();
void printHello();
void printWord(char*);
};
//talk.cpp
#include "talk.h"
using namespace std;
void Talk::printHello() {
cout << "Hello World";
}
void Talk::printWord(char* word) {
cout << "Hello" << word;
}
The second step I try to do is open a new project for iOS app and then set link to the library file, also include corresponding "talk.h" header file.
However, some errors happen on the header file even though I build library successfully.
The errors indicate that
"iostream" file not found
"Unknown type name 'class'; did you mean 'Class'?
any other errors...
I have try to rename controller.m to controller.mm, but it not fixes the problem
How to import the header file written in C++ for using library on iOS?
Thanks

A rough outline:
In Xcode (starting with an either one of the template iOS Application projects (or an existing one):
Create a new static library target: File -> New -> Target.... Select Framework Or Library, and then Cocoa Touch Static Library
Add library source code: Drag library source code into Xcode project. In the dialog that appears, select the build target created above.
Add project dependancy to library: Select Project in Project Navigation, the the iOS build target from Targets. Select Build Phases tab, then under Target Dependancies in the window, click on the + sign. A sheet opens (choose items to add) and the library target should be at thee top of the list.
Include Library in iOS Target: Under Link Binary with Libraries, click +. The library (a .a file) should be at the top of the list.
Link with libc++: As the step above. Select libc++ from the list.
Enable Objective-C++ compilation for any source code file that needs to include the library headers by changing the extension from .m to .mm
Build the iOS application target.
Xcode will have taken care of setting everything else up for you, including compiler flags and header search paths.

For the 1st part C++ compiles well with Xcode
I have written a simple tutorial
http://tutorialsios.blogspot.com/2013/09/c-beginers-code-for-objective-c.html
These code were written using Xcode and compiled in terminal
#include "functionOverLoading.h"
int main(int argc, const char * argv[]) {
..
..
return 0;
}
$g++ functionOverLoading.cpp –o functionOverLoading
$ ./functionOverLoading

You need to add the C++ Standard Library.
To do this, find Other Linker Flags in your project and add -lstdc++.

Related

Added C/C++ file to Eclipse Does not Compile

This has to be some kind of newbie question, but I have not been able to find any explaination.
I am running Ubuntu 18, and need to work with some C/C++ files. I've been using TI's CCS which is eclipse based on Windows for years.
I downloaded the Eclipse installer and ran it setting up for C/C++ developers.
https://www.eclipse.org/downloads/packages/installer
I created a new project. There were several different (unexplained) options such as CDT, MESON, MakeFile, ... I have tried several.
Creating a HelloWorld source file, it compiles and runs fine.
#include <stdio.h>
int main() {
puts("Hello World");
return 0;
}
Okay, so far...
Now I add a new source file. Called "OtherFile.c"
#include <stdio.h>
void OtherFunction() {
puts("Other Hello");
}
And of course, modify the original:
#include <stdio.h>
extern "C" void OtherFunction();
int main() {
puts("Hello World");
OtherFunction();
return 0;
}
When I try to build, it will not compile the new file. And (as expected) it tell me that "OtherFunction" is unresolved.
I have tried multiple project types (CDT, Meson, Makefile) even though there is no explanation of the differences. The newer file will not be compiled.
I tried changing the file extension from c to cpp and back. The newer file will not be compiled.
The TI version of CCS using Eclipse will include a source file when it's in the folder. However, in this environment, I cannot convince Eclipse to compile any other file than the one that was originally created by the new C/C++ project step.
And just as annoying is the fact that I can't right click either file and "Build Selected File". The menu option doesn't even appear.
This did not work for me:
eclipse c/c++ CDT build just one file
Can someone advice how to convince Eclipse to compile additional files?
TIA.
EDIT:
I can't upload here, so I just created something on GitHub.
These are two of the samples where I added a second file, and it ignores it.
https://github.com/scotty2541/EclipseExample
In all the other things I've done in Eclipse, it simply uses a default "recipe" like make does to compile the file.
If there is some way to manually tell Eclipse about it, that isn't explained anywhere I've been able to find. And seems to defeat the purpose of the IDE's behavior.
I was able to get it to behave as expected: By choosing a CDT managed build system, when adding a file to the project, it compiles it using the default recipe
Then, there is a setting which causes it to run the "builder" after a clean.
When I added the file as described originally, I also had to do a "clean" in order for the environment to include the additional file.

Build asimple c++ static library of ios(for unity), but cannot find the .a file

As the title mentioned, using macos 12.
example.hpp
extern "C"{
int summation();
}
example.cpp
#include "example.hpp"
extern "C"{
int summation()
{
return 10;
}
}
Then I create an Xcode project->static lib, add example.hpp and example.cpp, configure the build phase to ios only. Click on build, the xcode tell me "build succeeded", but I cannot find any .a file, even in the Xcode/DerivedData/*.
This is the first time I try to build c++ plugin for unity on ios platform, please forgive my ignorance if any.
Edit : I search the .a file shown in the full path(Image 00) but cannot find anything, color of the plugin is red color, weird
Solution is very simple, I create a new project, add the example.hpp and example.cpp into the project, set build target to ios only, click build, then the .a file is generated, I don't know why this happen, maybe some manipulation ruin the settings.

Autotools project and external libraries on Eclipse

I'm trying to build an Autotools project using Yocto ADT Plugin and Eclipse Luna.
I need to include some external libraries to the project and to be more specific the boost libraries.
Let's consider the easiest case scenario: header only library.
I should be able to #include into my project.
I'm trying to compile a test code:
#include <iostream>
#include <boost/lambda/lambda.hpp>
using namespace std;
int main(void) {
cout << "Hello World" << endl; /* prints Hello World */
return 0;
}
but I'm getting the error: "fatal error: boost/lambda/lambda.hpp: No such file or directory"
Of course I have to tell the compiler where to find the library.
I tried to do it in different ways but nothing succeded.
To make some examples:
Project -> Properties -> C/C++ General -> Path and Symbols
There I specified the path for downloaded libraries and for compiled libraries (not needed in this case but added for generality):
The include is correctly reported under project explorer but the error persisted.
Then I tried to work on Project -> Properties -> C/C++ General -> Preprocessor Include:
Still getting the same error.
I tried then to include configuring the Autotools adding the -I option:
Of course it didn't succeed either.
After every failed build attempt I run a "Clear Project" and "Reconfigure Project" just to be sure to start all over.
The strange thing is that if I select the boost/lambda/lambda.hpp in the editor and I do "Open Declaration" it finds the file:
At this point I don't know what to do, clearly I'm missing something.
Could you possibly help me ?
Additional Note: If I start an C++ Executable Project using GCC the library is recognized and I have no problems.
So I think the issue is within the Autotools or Yocto ADT.
I even added the boost libraries to my Yocto build and SDK but it's not working.
I managed to succesfully compile adding to the /src/Makefile.am the include to the libraries.
Still I don't understand why this is different from changing the Autotools configure flag.
If someone has an answer, please care to explain.

Include <string> not found compile error in Xcode 4.2

I'm getting include not found compile error in XCode. I have an iOS app project that i use Objective-c and c++ as mix.
Initially, i created one .h file and one .cpp file in my ios project. Then, I renamed the .cpp file to .mm file.
Here is my .h file;
TestLog.h
#ifndef CalculatorDemo_TestLog_h
#define CalculatorDemo_TestLog_h
#include <string>
using namespace std;
class TestLog
{
private:
string logString;
public:
void Log(string logMessage);
};
#endif
TestLog.mm
#include "TestLog.h"
void TestLog::Log(string logMessage)
{
//this->logString->append(logMessage);
}
What am I missing? Do I need to add std c++ library to my targetS? Something related to Search Header Paths?
I just need to use string type.
Thanks much for in advance
select project -> build setting -> apple LLVM compiler 5.1 -> language
In Compile Sources As change to Objective-C++
There's a quirk in XCode. I noticed it in 7.3. Most projects recognize .mm files and the STL, while one project I had did not. The fix was that I had to click on the top-left project icon, then click Targets > Build Phases > Link Binary with Libraries > and add in AppKit.framework. Next, I had to click Targets > Build Settings > search on "Compile Sources", and set it to "Objective C++" on all possible columns. Then, do a Clean and then a Build from the Product menu. This compiled properly then. Then, go back to that Compile Sources again and set it back to "According to File Type" on all possible columns. Then, click Build from the Product menu again. At that point, it compiled properly and allowed me to utilize the "according to file type" option, which I like better.
Oh, and if doing Cocoa stuff, don't forget to add the following header in your files:
#import <Cocoa/Cocoa.h>
And if doing command line stuff, don't forget to add the following instead of the Cocoa header:
#import <Foundation/Foundation.h>
i believe you need to include the whole path to the library. similarly to say "foundation" & "uiview" frameworks.
#import <Foundation/Foundation.h>
or
#import <UIKit/UIKit.h>
and yes, make sure you add the library to your target.
So I was having this issue with the Cocoapods library Bypass and none of these solutions did anything. The problem was with a file which Cocoapods creates called an umbrella header. This is located in <POD_NAME>/Support Files/<POD_NAME>-umbrella.h. Delete it, and it should build just fine.
Now for the explanation of why this is necessary: the umbrella header is mixing both C++ and Objective-C code directly in a header which is a big no-no apparently and ends up completely breaking the C++ imports. By removing it (which seems to have no effect?) this conflicting import which Cocoapods unknowingly created will go away.
Ran into this with xcode 12.4 with a project that is objective-c, but where I need one C++ modul. Solution: wrap the contents of the .h file in:
#if defined __cplusplus
declarations
#endif
Apparently xcode is not good at detecting a mix of sources.
see Expected ; after top level declarator, error in xcode
This often happens when Xcode doesn't understand that a C++ header file you've imported into Objective-C is actually for C++ code.
So you can solve this problem by finding the Objective-C file that imports C++ code, and simply change its extension from .m to .mm

GCC: Specifying static/dynamic libraries to build against

I have a simple C++ project that is structured as following:
-A base project (ie: contains main() ), and links against everything else
--A few custom libraries that are all built as static libs (ie: .a files)
---One of these static libraries uses features in a shared objective file (ie: a .so file)
So, for example, this is how the project would appear (in a a tree view) at link time, after all the initial compiling has completed:
-myApp (the main application)
--libaudio.a (the audio library I made)
--libnetwork.a (the networking library I made)
--libvideo.a (the video library I made)
--libboost.a (boost library)
Initially, this project build just fine. I just had to make sure I had a simple line in my makefile like this:
LIBS+=audio network video
Recently, I had to change how my audio library works. I now am required to use a third-party library, and all I have is the header file (.h) and the shared object (.so) files. So the new structure at link time looks like so:
-myApp (the main application)
--libaudio.a (the audio library I made)
---libthirdparty.so (contains third-party audio handling functions)
--libnetwork.a (the networking library I made)
--libvideo.a (the video library I made)
--libboost.a (boost library)
This, in effect, means that I have an application with a static library linked in which makes calls to an external shared object. So, I put the header file in the appropriate location so I don't have any build errors when compiling libaudio.a, and put the libthirdparty.so file in a location where the linker searches for all my installed libraries.
At this point, I cannot get the thing to build. It just doesn't see libthirdparty.so file, even though I know it is in a location that the linker searches by default. For some reason, wrapping my libaudio code, as in the example below (borrowed from www.cplusplus.com) fixes the build error:
my_C_CPP_Header.h:
#ifndef MY_C_CPP_HEADER
#define MY_C_CPP_HEADER
/*check if the compiler is of C++*/
#ifdef __cplusplus
extern "C" {
int myOtherCfunc(int arg1, int arg2); /* a C function */
}
#endif
void myCppFunction1(); /* C++ function */
void myCppFunction2(); /* C++ function */
/*check if the compiler is of C++ */
#ifdef __cplusplus
}
#endif
#endif
Now, I have a new problem though. Now that it's building, it no longer statically links in libboost.a, and instead is crashing at startup due to libboost.so not being present. So, somehow this setup breaks how libboost is compiled in if I manage to get it to build at all.
Any suggestions are welcome. Thank you all in advance.
In the end, there was a "LIBPATH=" instead of a "LIBPATH+=" statement overriding the library include paths. Resolved.
Thank you all for your help.