Calling a method in a static library - c++

I'm trying to write a C standard library from scratch on OSX with gcc. When I try to include a header file from my library in my test program, I get the error that it isn't defined. I try to use the -nostdlib flag but I still can't include my file.
My test program:
#include <math.h>
#include <bool.h>
#include <ctype.h>
#include <string.h>
#include <io.h>
int main(){
int x = sin(0.5);
int y = pow(2,3);
int z = abs(12);
myiofunction(7);
exit(0);
}
math.h,bool.h,ctype.h,string.h, and io.h are defined in my library. What am I doing incorrectly?
EDIT:
The error message that I am getting is:
helloTest.c:10:10: fatal error: 'bool.h' file not found

Header files aren't compiled into a static library. They have to be available to both library and program.
Therefore, when compiling your program, make sure to specify the -I options to let the compiler find your library's header files.

In order for it to use your own standard library as well, you have to use the -I option to include your library:
gcc -nostdlib -I/path/to/my/headers/ ...
So if the headers for those files were located in ./include, you'd compile with:
gcc -nostdlib -I./include/ ....
Of course you need to provide the object code for these functions at some point. Then you can link them all together using ld with -lgcc to resolve any internal GCC subroutines.
GCC Linking Options: https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

You need to write :
#include "bool.h"
Check that out:
Include Syntax

If you use it won't work anyway. You have to typed as "bool.h"
and the other thing is -l option.
Check it out : https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
If you specifiy the default location : -R [PATH]

The library to include is
#include <stdbool.h>

Related

How to use math lib in OpenACC with g++-11? [duplicate]

I have this simple code:
max = (int) sqrt (number);
and in the header I have:
#include <math.h>
But application still says undefined reference to sqrt. Do you see any problem here? It looks like everything should be okay.
You may find that you have to link with the math libraries on whatever system you're using, something like:
gcc -o myprog myprog.c -L/path/to/libs -lm
^^^ - this bit here.
Including headers lets a compiler know about function declarations but it does not necessarily automatically link to the code required to perform that function.
Failing that, you'll need to show us your code, your compile command and the platform you're running on (operating system, compiler, etc).
The following code compiles and links fine:
#include <math.h>
int main (void) {
int max = sqrt (9);
return 0;
}
Just be aware that some compilation systems depend on the order in which libraries are given on the command line. By that, I mean they may process the libraries in sequence and only use them to satisfy unresolved symbols at that point in the sequence.
So, for example, given the commands:
gcc -o plugh plugh.o -lxyzzy
gcc -o plugh -lxyzzy plugh.o
and plugh.o requires something from the xyzzy library, the second may not work as you expect. At the point where you list the library, there are no unresolved symbols to satisfy.
And when the unresolved symbols from plugh.o do appear, it's too late.
I suppose you have imported math.h with #include <math.h>
So the only other reason I can see is a missing linking information. You must link your code with the -lm option.
If you're simply trying to compile one file with gcc, just add -lm to your command line, otherwise, give some informations about your building process.
Just adding the #include <math.h> in c source file and -lm in Makefile at the end will work for me.
gcc -pthread -o p3 p3.c -lm
Here are my observation, firstly you need to include the header math.h as sqrt() function declared in math.h header file. For e.g
#include <math.h>
secondly, if you read manual page of sqrt you will notice this line Link with -lm.
#include <math.h> /* header file you need to include */
double sqrt(double x); /* prototype of sqrt() function */
Link with -lm. /* Library linking instruction */
But application still says undefined reference to sqrt. Do you see any
problem here?
Compiler error is correct as you haven't linked your program with library lm & linker is unable to find reference of sqrt(), you need to link it explicitly. For e.g
gcc -Wall -Wextra -Werror -pedantic test.c -lm
I had the same issue, but I simply solved it by adding -lm after the command that runs my code.
Example.
gcc code.c -lm

How to link dynamic library "-li2c" with Cmake? (undefined reference to `i2c_smbus_write_byte_data`)

As I'm rather new to Cmake usage, I don't really know how to solve this problem. In my C++ code, I use functions from the Linux i2c library, as follows:
extern "C" {
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
}
#include <sys/ioctl.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
bool cpi2c_writeRegister(uint8_t address, uint8_t subAddress, uint8_t data) {
return i2c_smbus_write_byte_data(address, subAddress, data) == 0;
}
I usually compile with Cmake using CMakeLists, but now it doesn't work since it states: undefined reference to 'i2c_smbus_write_byte_data'. I tried with G++ to link dynamically:
g++ -std=c++11 -Wall -c main.cpp
g++ -std=c++11 -o Main main.o -li2c
This worked well and there are no problems. The problem is I really need to compile with CMakeLists, so do you know a way how to achieve this? Cmake does not find the package by default (since it has no .config-file) and I don't know where the functions from i2c/smbus.h are defined.
Thanks for your help!
Using pkg-config is generally preferred to link libraries that have a .pc file.
But as libi2c does not seem to install a .pc file you can use target_link_libraries() directly by providing the library name. For simplicity and portability use the "Plain library name" (see the target_link_libraries documentation).
target_link_libraries(main i2c)
CMake will take care of expanding the plain library name to -li2c, i2c.lib, or whatever is suited to your build environment and operating system.
Step 1: add
target_link_libraries(${PROJECT_NAME}
i2c
)
To your CMakeList.txt.
Step 2: Declare the headers as "C",
extern "C"
{
#include<linux/i2c-dev.h>
#include <i2c/smbus.h>
}
Because libi2c.so is a dynamic library compiled with GCC.
If you do not declare it explicitly, the g++ will generate different function names in the symbol table thus the ld command cannot find any match in the i2c library.
The answer is, you can use the command target_link_libraries() after creating the executable. You have to provide the name of the object and a path to the .so-file (usually found in /usr/lib). In my case, that would be:
target_link_libraries(main, "/usr/lib/aarch64-linux-gnu/libi2c.so")

how to compile code using external dll library

I want to compile program with one file test.cpp, which use external library (i have dll and lib). How to do that?
My test.cpp
#include <ExternalLib.h>
#include <iostream>
#include <stdio.h>
#define USE_USB_AUTO_CONNECT 1
int main()
{
printf ("Characters: %c %c \n", 'a', 65);
return 0;
}
ExternalLib is provided by third part company with files: ExternalLib.lib and ExternalLib.dll. There are also files with extension so and a.
When I compile with command:
g++ test.cpp
I get error:
test.cpp:1:20: fatal error: ExternalLib.h: No such file or directory
#include <ExternalLib.h>
Thanks for your help.
I think you are trying to use dll files (compiled in Windows) under Linux, that will not work.
Anyway your error is that the compiler isn't able to locate your header file, to solve this you have several options:
1) Provide the include path when compiling using -I switch
i.e.: g++ test.cpp -I<path to your include directory>
2) Copy the ExternalLib.h to the same directory in which test.cpp lies and use #include "ExternalLib.h" instead of #include <ExternalLib.h>
3) Provide relative path to ExternalLib.h starting from the directory in which test.cpp lies. That is, replace #include <ExternalLib.h> for #include "../../external/ExternalLib.h"
This will solve the No such file or directory problem. Then you will also have to provide the binary/library files using -L (for library path) and -l (for library file) switches.

Linking C++ static Library in C using gcc

In the following code, I am trying to call a dummy function written in C++ (using C++ header files like ap_fixed.h, ap_int.h) from a C function. The code runs fine when I compile with g++. But when I use gcc for compiling test.c, it throws an error because I have included a C++ header file which is a valid error.
Is there any workaround to compile using gcc? I have read from some posts that it is not a good practice to merge C/C++ code in this manner. Please enlighten me if there are any serious repurcussions of working with a large C codebase and doing similar stuff.
Thanks
Header File: testcplusplus.h
#include "ap_fixed.h"
#include "ap_int.h"
#ifdef __cplusplus
extern "C" {
#endif
void print_cplusplus();
#ifdef __cplusplus
}
#endif
testcplusplus.cc
#include <iostream>
#include "testcplusplus.h"
void print_cplusplus() {
ap_ufixed<10, 5,AP_RND_INF,AP_SAT > Var1 = 22.96875;
std::cout << Var1 << std::endl;
}
test.c
#include <stdio.h>
#include "testcplusplus.h"
int main() {
print_cplusplus();
}
Commands Used:
g++ -c -o testcplusplus.o testcplusplus.cc
ar rvs libtest.a testcplusplus.o
gcc -o test test.c -L. -ltest
Error:
In file included from ap_fixed.h:21:0,
from testcplusplus.h:1,
from test.c:2:
ap_int.h:21:2: error: #error C++ is required to include this header file
The problem here is that the C++ header ap_fixed.h is included from the C program test.c (indirectly via testcplusplus.h).
The solution is to remove the include of headers "ap_fixed.h"
and "ap_int.h" from testcplusplus.h and include them directly from testcplusplus.cpp. The C program doesn't need to know about these anyway, only the C++ wrapper uses them directly.
In a larger example it might be appropriate to split testcplusplus.h into two headers: one that contains only declarations of the external interface you are presenting to the C environment, and another containing the rest - declarations needed internally in the C++ implementation and any required includes.
Once you have done this, you will still face linking errors because the executable that is produced will contain references to symbols from the C++ runtime libraries, plus any other libraries that your C++ code uses. To solve this, add -l directives when compiling the final executable, eg:
gcc -o test test.c -L. -ltest -lstdc++
You do not need to include ap_int.h and ap_fixed.h at this point, as the declaration of the print_cplusplus function does not need those definitions.
Rather, include them in testcplusplus.c, so the C compiler can only see the C compatible interface of the C++ code.

Confusion between including header files and source files in main program

I have heard that we should write the declarations in a header file and the definition in a source file, with both the source and the header having the same name. And then just include the header in the source.
Here is an example myFile.h:
void printer (void);
Here is the implementation of printer in myFile.cpp:
#include "myFile.h"
#include <iostream>
using namespace std;
void printer ()
{
cout<< "I am a printer";
}
Here is my main.cpp:
#include "myFile.h"
int main ()
{
printer();
return 0;
}
Now when I run the program, I get the expected error: undefined reference to printer. But when I see code on github or other projects I see that usually they have included the header file and not the source file. I also tried using the header guards ifndef but still the same error came.
The main program is successfully compiled if:
If i include myFIle.cpp in myFile.h
If i include just myFile.cpp in main
What I the general practice while doing the same?
You should include your myFile.cpp in the linking process:
g++ myFile.cpp main.cpp
The error message undefined reference to printer is actual a linker error, not a compiler error.
Explanation
If you use only g++ main.cpp compiler won't create code from myFile.cpp. He knows that there should be a function with the signature void printer(void), but he doesn't now yet where this function is. He completely ignores this fact, since you can provide pre-compiled object files ("myFile.o") and link those later:
g++ myFile.cpp -c # compile myFile.cpp
g++ main.cpp -c # compile myFile.cpp
g++ myFile.o main.o # link both files together.
-c will tell g++ only to compile the files, but not link them together to an executable. This is done by a linker (g++ will probably call ld in your configuration). The linker will create an executable which contains all needed libraries like libc++ and actual code.
IDE remarks
If you use an IDE make sure that all needed files are included in the project. This includes all header and source files and linkage options for additional libraries.
When yourself define a header file and want to include it, you should enclose it "", such as :
#include "myFile.h"
#include "myFile.h" // would be better.
It seems you forgot the " surrounding the include.
You should use
#include "myFile.h"
or
#include <myFile.h>
the later is rather for system libraries. Both forms differ in the way the search the file.
You find more details on
http://msdn.microsoft.com/en-us/library/36k2cdd4%28v=vs.71%29.aspx