How to link static library without using -I option - c++

I have created C++ static library using object files (which has many sub directories). After creating static library created a C file and a wrapper file (header file which I have under C++ directories). Now I'm trying to compile the C file by linking the C++ static library it gives error for the header file
error : no such a file or directory.
When I use -I option (-I C++ header files location) compiled successfully and able to run. But I would like to use the static library without including header files location i.e only adding static library itself C program should compile successfully.
Below is the source:
Edit:
I have the below files under libbasic folder:
testdemo.h
#ifndef TESTDEMO_H
#define TESTDEMO_H
#include<iostream>
#include<string>
using namespace std;
class testdemo
{
public:
testdemo();
void CallingTestDemo();
};
#endif // TESTDEMO_H
testdemo.cpp
#include "testdemo.h"
testdemo::testdemo()
{
}
void testdemo::CallingTestDemo()
{
`cout <<" CallingTestDemo!!!!!!\n";
}
testbasic.h
#ifndef LIBBASIC_H
#define LIBBASIC_H
#ifdef __cplusplus
#include<iostream>
#include<testdemo.h>
using namespace std;
class Libbasic
{
public:
Libbasic();
void Display();
void DisplayName(char* name);
};
#endif
#ifdef __cplusplus
extern "C" {
void displayfromC();
void displayfromCName(char* name);
}
libbasic.cpp
#include "libbasic.h"
void displayfromC()
{
Libbasic llb;
llb.Display();
}
void displayfromCName(char* name)
{
Libbasic lb;
lb.DisplayName(name);
}
Libbasic::Libbasic()
{
}
void Libbasic::Display()
{
cout <<" C called C++ API \n";
testdemo td;
td.CallingTestDemo();
}
#endif
#endif // LIBBASIC_H
I compiled the above program and created library libbasic.a
Now Im creating C API file outside the libbasic folder to call the above functions used in C++
testApi.c
#include<stdio.h>
#include <libbasic.h>
int main()
{
displayfromC();
}
Now im trying to create output using the below
gcc -o testdemo testApi.c -L ./libbasic -lbasic
Which giving libbasic.h: no such a file or directory error.
The basic Idea is create a library and API functions which can be used in any machine. If I have multiple folders and header files in C++ code then need to include all the folders while creating C application which requires to export header files too. I dont want to expose all the source to other users.
Kindly let me what mistake im doing and also how to achieve this.

A header file is not a wrapper.
If you have functions in a library, whether static or dynamic, you must have their declarations (often called "prototypes") in your code.
That is how C and C++ work so header files are integral part of any library.
As for the location of header files, these languages give you three options:
Use <filename.h> for standard include header path.
This path depends on your OS and compiler, but as long as your header file is there, you will not need to specify the path explicitly in compilation command.
Use "filename.h" for files in your local source directory, i.e. same directory where your *.c or *.cpp files reside.
The compiler can look there automatically as well, but if the header is in a sub directory, you will need to specify the relative path in your include statement.
#include "mylib/myheader.h"
Add additional search path for header files using a parameter (such as -I for gcc).
Finally, similar rule applies to the library object file it self (*.a, *.lib).
You will need the -L parameter in addition to the -l parameter if your library is not in a standard library path known to the linker.
Note that you never specified which compiler you are using, so I am guessing based on parameter names it is from gcc family or similar.
A way to alter the search path and tell the compiler where to find your library files will differ based on compiler type, but the principle is the same.

Related

c++ Library with nested includes

So I'm trying to create my own library in C++ and use it in another project.
So far it works with example code, but I have to include other libraries in my own library. So the problem is, that when I include the header files off my library,
the include paths in the header files are messed up.
A simple solution would be to add the search directories, but I don't think,
thats how its supposed to be resolved.
Sample Code - Library header file:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int test();
The source file:
#include "sample.h"
int test() { return 20; }
Now the project in which I want to include the sample
#include <sample.h>
int main() { int a = test(); }
The problem is, that the include copies the code from sample.h directly into the main.cpp and the search directories for the other includes from sample.h are no longer defined
A simple solution would be to add the search directories, but I don't think, thats how its supposed to be resolved.
This is certainly the easiest solution since it requires no modifications to the code, and is usually an acceptable thing to do - however obviously it means the project can call the functions from glew.h and glfw3.h
The only alternative is to ensure the headers are not included by the library header, but instead by the source.
IE:
Library Header:
int test();
Library Source:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "sample.h"
int test() { return 20; }
And the project's source file left unchanged.
This requires that the types defined in glew.h and glfw3.h are not part of the public interface exposed by your library.
Eg, if your library had a function like:
GLFWwindow* window = openWindow(...);
You would need to change it to:
Library header:
struct WindowHandle;
WindowHandle* openWindow(...);
Library source:
struct WindowHandle{
GLFWwindow* window;
};
WindowHandle* openWindow(...){
WindowHandle* result;
//... do stuff...
result->window = //whatever;
return result;
}
This approach requires changing the library code, but has the advantage that the users of the library can't directly call the things the library depends on (glew and glfw in this case). This is particularly beneficial if you want to support multiple platforms, you could have a source file for opening windows via glfw, and another using direct x. The library's public interface would not need to be changed to support both backends.
If you want to know more about this approach try searching for "Opaque data types"

Header only library inline not working

I am struggling with my library design. I want to create a library to be used in my future projects (header only for now...)
I have this file structure:
C:\Libs\MYLIB
- Tools.hpp
- Tools.cpp
The code looks like this:
Tools.hpp
#pragma once
class Tools
{
public:
Tools();
~Tools();
};
Tools.cpp
#include "Tools.hpp"
inline Tools::Tools()
{
}
inline Tools::~Tools()
{
}
And then there is is another project, in a totally different folder including this file:
#include <MYLIB/Tools.hpp>
int main()
{
Tools t;
return 0;
}
But I always get this error:
undefined reference to Tools::Tools()'
undefined reference toTools::~Tools()'
When I create a .hpp file only with inline implementation inside my class, like this:
#pragma once
class Tools
{
public:
Tools(){};
~Tools(){};
void DoSomething(){};
};
it works (so my include paths are correct), but I don't want to bloat my .hpp file (I want to use doxygen later on, and keep my declaration from implementation).
I know using inline can be ignored by the compiler, I guess this is what happens here?! So what is the best way to create a private header only library
My specs:
Win 10 with CodeLite
MinGW (g++)
Another question:
Should this line in Tools.cpp
#include "Tools.hpp"
better be like this:
#include <MYLIB/Tools.hpp>
You can use an ad-hoc static lib, which is convenient for libraries that are small and/or change often and thus don't provide much benefit compared to the overhead of versioning/compiling/distributing separately. The idea is that you separate headers/sources as normal, but you just #include the .cpp file in one translation unit. Be aware that this technique has its benefits, but also limits!

How to use a function defined in another file with g++?

This is a really basic question, and I have found a lot of conceptual answers online, but failed to actually make it work.
Here is what I have:
file source.cc
#include <iostream>
int myfunc() {
return 42;
}
int main() {
return 0;
}
and then I create an object file source.o via:
g++ -c source.cc
finally, I use
ar rvs source.a source.o
to get the source.a static library.
Now, here comes trouble.
file user.cc looks like this:
#include <iostream>
#include <source.a>
int main() {
std::cout << myfunc();
}
where I evidently want to use the function defined in the library, but when trying to compile the user.cc:
g++ user.cc -o user
the error I get is:
user.cc:2:22: fatal error: source.a: No such file or directory
compilation terminated.
#include is compile time and must be C/C++ header (not library) containing e.g this
extern int myfunc();
than you have to use linker to compile it all togehter (specify all the files needed on the command line)
In addition to what others already wrote on the syntax to properly use g++ on the command line, you may want to consider the following notes on your code organization.
In your library code, you should not define the main() function. The definition of main() should instead be part of the code that uses your library, i.e the file user.cc in your example.
Moreover, you may want to distribute to the clients of the library a header file, that they can use to import the declarations of the functions exported by the library.
So, consider defining some files like this:
Header File:
// library.h -- Public header for your library's clients
#pragma once // or use #ifndef/#define/#endif "header guards"
// Functions exported by your library:
// their *declarations* go in the library's public header file;
// their *definitions* go in the library's implementation file(s) (.cc, .cpp)
// (exception: inline functions/methods, that are implemented in headers).
int myfunc();
// Add some other exported functions...
// NOTE: "extern" not needed in C++!
Implementation File:
// library.cc -- Library implementation code
#include "library.h" // library public header
#include <...> // headers required by this implementation code
// *Define* functions exported by the library
int myfunc() {
return 42;
}
// ...other function implementations...
Then, the library's client will just do:
File containing main() and using your library:
// main.cc (or user.cc or whatever you call it)
#include <iostream> // For std::cout, std::endl
...#include any other required header file...
#include "library.h" // Your library public header file
int main() {
// Call library's function
std::cout << myfunc() << std::endl;
}
// NOTE: main() is special: "return 0;" can be omitted.
Don't #include a library archive. It does not contain source code. It contains object code. Put it on the linker's command line.
Compile with g++ -c user.cc.
Link with g++ -o user user.o source.a.
In C++ (and C99), every function you call much be declared ahead of time. To do this you provide the "signature" of the function, without the the definition. In your case, this would be the statement
int myfunc();
which tells the compiler that myfunc is a function which takes no arguments and returns an int. Typically you would include this function declaration in a header.
A .a file is a compiled archive which does not contain C or C++ code, so #include-ing it into a C++ file will not work. Instead you need to create a C or C++ header, and add the .a archive to the list of files to be linked into the final executable. With g++, this is quite easy, you can say
g++ user.cc source.a -o executable
for example.
By default the #include <...> construct (with angle brackets) search system directories to find the specified files. To search other directories you can use the -L option, and to link with your library you need to use source.a in the command line. Like this:
g++ user.cc -L/path/to/library source.a -o user
A couple of ideas to add to the discussion
1) You should create a header file called source.h that contains the line
int myfunc();
or,
extern int myfunc();
2) In user.cc at the top should be a line
include "source.h"
This will tell the compiler the function is defined
3) I think you should take the main function out of source.cc, or at least make it static
As others have pointed out, you can't include a library file (source.a)
your compile and link process should work as is.
You can use headear files using #include. If you want to use libraries you have to tell the linker where to look for library files.
Check these articles for static and dynamic libraries:
Static and dynamic libraries
Using libraries in VS2005
Using libraries in Code::Blocks

Accessing functions from external files in class definition

I'm trying to access functions from another file for use inside my class definition:
// math.cpp
int Sum(int a, int b){
return (a + b);
}
// my_class.cpp
#include <math.cpp>
#include <my_class.h>
int ComputeSomething() {
...
return ::Sum(num1, num2);
}
Despite my best efforts, I can't get the compiler to spit out anything outside the likes of ::Sum has not been declared or Sum was not declared in this scope.
I'm trying to wrap my head around code organization in C++, any help appreciated.
It might be worth noting that I'm programming for Arduino.
To be able to access functions from a user-defined library, best divide that library into a .h (or .hpp) and a .cpp file. I understand you have actually done this, but tried various options – among them the inclusion of the .cpp file – for the sake of finding a solution.
Still, to ensure things work as expected, the declarations of functions and classes should go into the .h file, best protected by something like
#ifndef MY_H_FILE
#define MY_H_FILE
/* ..Declarations.. */
#endif
Then to include the .h file (I'll assume it's named my.h), either use
#include "my.h" // path relative to build directory
or
#include <my.h> // path relative to any of the include paths
The latter only works if my.h is found on an include path previously known to the compiler (e.g. what is specified using the -I command line option in GCC). The former works if the path to the .h file given is relative to the directory your are building from.
Finally, do not use a file name that can be confused with a system library (such as "math.h"), especially if you are using the <...> syntax, as the include path will definitely include the system library header files.
Have you followed the instructions given here?
User-created libraries as of version 0017 go in a subdirectory of your
default sketch directory. For example, on OSX, the new directory would
be ~/Documents/Arduino/libraries/. On Windows, it would be My
Documents\Arduino\libraries. To add your own library, create a new
directory in the libraries directory with the name of your library.
The folder should contain a C or C++ file with your code and a header
file with your function and variable declarations. It will then appear
in the Sketch | Import Library menu in the Arduino IDE.

Importing Functions from a different C file

I want to import functions from another file in Microsoft Visual C++ 6.0. How can i do this? I have tried with this as follows:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#import <functions.cpp>
where functions.cpp is the file name from where I want to import the functions. But this gives an error: F:\CC++\Term Project\Dos Plotter\Functiom Plotter.cpp(6) : fatal error C1083: Cannot open type library file: 'Functions.cpp': No such file or directory
How can I solve this problem?
The #import directive is used with type libraries, often COM or .Net, not C++ source files. For complete details, see the MSDN page.
In order to include C++ functions from another file, you typically want to use the #include directive (details). This includes the code from the given file during compilation. Most often, you should include a header containing the function prototypes; it is possible to include code files, but not commonly needed or always safe.
To do this, you should provide two files, a header and a source file, for your functions.
The header will read something like:
#pragma once
void Function(int arg);
and the source:
#include "functions.hpp"
void Function(int arg) { ++arg; }
To use this in another file, you do:
#include "functions.hpp"
void OtherFunction()
{
Function(2);
}
You should also note that a header should typically be included only once. The MSVC-standard method of guaranteeing this is to add #pragma once to the beginning.
Edit: and to address the specific error you've posted, which applies to both #import and #include, the file you're attempting to include must be somewhere within the compiler's search path. In Visual Studio, you should add the necessary path to the project includes (this varies by version, but is typically under project properties -> compiler).
1) Did you mean functions.hpp? C/cpp files should not be #included unless you know very well what you're doing.
2) Add the location of the file to the custom include path in the project properties, or use the include "foo" format instead of include <foo>
3) Import is undefined in C. You need to separate prototypes and implementations, include-guard the prototypes file, and #include the prototypes file.
having the file functions.cpp on the same dir, use include "functions.cpp" instead
Name the file imported-function.hpp, and make sure that it is in the same dir. Or, you could link it to
Linux: /home/uname/appfolder/imported-function.hpp
Windows: C:\Username\uname\appfolder\imported-function.hpp
ChromeOS: /home/chronos/u-4e4342ea6b3b92244e7d4753922f0dc7125f4a1d/MyFiles/appfolder/imported-function.hpp