I have a custom header file example.h which has prototypes for a few functions. There is a .C file example.c that I implemented which "includes" (#include "example.h") and has the implementations of the functions that has prototype in example.h.
Now, I have another function test.c that has to call the functions that are prototyped in example.h and are implemented in example.c. How Can I do it?
You need to link them all at the end (assuming you have already included the prototypes into your test.c). So if you're compiling, you can compile both of the .c files together into one executable. More commonly, however, is to compile these without linking (which produces object files). Then, at the end, link all of the object files together. To do this depends on your compiler, but an example would be:
gcc -c -o example.o example.c
gcc -c -o test.o test.c
gcc -o my_application test.o example.o
Or, for a small project, this works just as well
gcc -o my_application example.c test.c
Just #include "example.h" in test.c (and don't forget to link all of the object files!)
Related
I'm using pmemobj_create from https://pmem.io/pmdk/manpages/linux/v1.4/libpmemobj/pmemobj_open.3 in my own code foo.c. It takes arguments PMEMobjpool *pmemobj_create(const char *path, const char *layout, size_t poolsize, mode_t mode). When compile foo.c directly to foo.o, than link foo.o with test.o, everything works fine.
I used the following compilation commands.
gcc -c foo.c -o foo.o
gcc test.o foo.o -o test
But when I compile foo.c to libfoo.so first, using
gcc -c -fPIC foo.c -o foo.o
gcc -shared -o libfoo.so foo.o
Then link it with test.o,
the compilation succeeded, but at execution, the execution of the function pmemobj_create fails with an error indicates Invalid argument. My assumption is that the way I compile foo.c might be wrong, which causes the arguments I passed into pmemobj_create to be invalid. But how can I fix it? Thanks for any suggestions!
Does .so file change any types?
If you think of MIME types, no. Check with file(1). But in C++ code compiled by GCC, type information is encoded by name mangling (and some C-callable libraries are coded in C++). So use extern "C" (for public function names in plugins) as suggested in the C++ dlopen mini-howto.
A shared library (or *.so file) does not contain a lot of type information. Read about the ELF format. At link time, there is just a difference between data and code, and both named functions and data have a name, an alignment, a size (in bytes) an not much more type information (except being data, function and their segment). Check with readelf(1), objdump(1), nm(1).
On Linux: read how to write shared libraries then compile your plugin with gcc -Wall -Wextra -g -fPIC -O1 foo.c -shared -o libfoo.so.
Perhaps you should also append -lpmemobj to the above gcc command.
Learn to use the GDB debugger. Your main program needs to be compiled with gcc -Wall -Wextra -g then linked with -rdynamic -ldl passed to gcc
Use also not only gdb(1) but also strace(1), pmap(1), ltrace(1) to understand what is going on at runtime.
Read more about elf(5), ld.so(8), dlopen(3).
I am having issues linking a library (termbox) when compiling. I get the error:
make: *** No rule to make target `termbox.h', needed by `test.o'. Stop.
Makefile:
edit: test.o
gcc -Wall -o edit test.o
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -ltermbox/src
Include:
#include "termbox/src/termbox.h"
I have also tried using the compiled library but ran into similar issues. Do I have to use some sort of combination of specifying the header file and the location of the compiled library?
The directory of my termbox folder is in the same directory as test.c.
Thanks!
You have managed to compile and include the header file for the library, but you did not yet tell the compiler where the code (definitions) are - i.e. you did not tell it to link in the library yet.
You will need to do that next, this is done in a similar way to telling the linker what files to link, but with some extra syntax. It appears to be a static library (.a suffix) so you can link like this:
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -Itermbox/src -Lsrc -ltermbox
Where -L... specifies where libraries can be found and -l... specifies the library name to link to minus the lib prefix and the .a or .so suffix. Also note that order is important, so leave the library linkage at the end.
More on library linking order here
UPDATE
Sorry I added the linking to the wrong line! - here is the updated answer:
# The linker stage
edit: test.o
gcc -Wall -o edit test.o -Lsrc -ltermbox
# Compile stage
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -ltermbox/src
If I have a header file List.h that contains the prototypes of the functions related to a list, the definitions of the functions are in a source file (c file) List.c. Both List.c file and the main.c file(or any source file representing the main program) include the List.h file. Now the main program has the prototypes of the list functions, but how did the definitions of the functions get included in the main program while there is no inclusion for the List.c file into main.c file? It is not about that the List.h and List.c files have the same name.
I am working on Windows and using MS Visual Studio.
For your scenario, you compile List.c to List.o (or maybe List.obj if you're working on Windows), and you compile main.c to main.o. Then you run the compiler again to link the two object files together, along with any other necessary libraries.
If you use GCC (the GNU C Compiler from the GNU Compiler Collection), then you might use:
gcc -Wall -Werror -std=c11 -c List.c
gcc -Wall -Werror -std=c11 -c main.c
gcc -Wall -Werror -std=c11 -o program main.o list.o
If you need to specify libraries, you'd add them after the object files.
You probably automate all this with a makefile, too.
They are compiled separately. After compilation most compilers generate object files containing executable code, relocation, symbolic, debugging and some other information. Those object files are next "merged" together by linker program which uses the information from the object files to create the correct executable file.
This is of course a very simplified description and if you want to know more you should read more about it on internet.
I've just started to create my own C libraries to keep my commonly used functions tidy. However, I've hit a new problem and I struggled to find information on the best route to take.
I generate my library of two functions using the following:
gcc -I. -c -fpic rand_site.c
gcc -I. -c -fpic rand_spin.c
gcc -shared -o libstatphys.so rand_site.o rand_spin.o
Each of these source files contained a single function. I was hoping to create a third function for my library that uses the two functions above but I'm not sure how to use functions from within the same library.
Am I going about this the right way? What is the best practice for doing this?
Yes, you can.
Create a header file rand_site.h and put the declaration of the function defined in rand_site.c in it.
Create a header file rand_spin.h and put the declaration of the function defined in rand_spin.c in it.
Use #include to include the two .h files in the third file, say foo.c.
Then compile foo.c and add it to the library using:
gcc -I. -c -fpic foo.c
gcc -shared -o libstatphys.so rand_site.o rand_spin.o foo.o
If you would like to create a second shared library that has foo.o, you can use:
gcc -I. -c -fpic foo.c
gcc -shared -o libfoo.so foo.o -lstatphys
If you would like to create an executable using foo.o, you can use:
gcc -I. -c foo.c
gcc foo.o -lstatphys
I have looked at these links : This one
and This
and a couple of other similar ones.
None of the answers given here are working methods are working.
I have a two source files a1.c , a2.c and two header files a1.h and a2.h . I want to include the header files in both these files (and a2.c in a1.c as there is a function I need to use from a2.c)
I have included
#include "a1.h"
#include "a2.h"
in the source files of a1.c
I'm using GCC on Ubuntu. and using the command gcc a1.h -o a1.out -lm
and that didn't work.
I tried with
gcc -c -I/Home/Documents/ctests/ a1.c -o a1.out
as well as
gcc -c a1.c -I/Home/Documents/ctests/ -o a1.out
My spellings are okay as well (there's hardly any room for error there with one letter and a number as the filename anyway).
Also, all the files are in the same folder.
I know this may be a trivial question but I am stuck on this one and would appreciate any help. I am relatively new to programming and completely new to Linux and Unix as far as using the command line goes.
Many thanks!
gcc -c
tells gcc to compile the file to object (the .o files you see everywhere). To be linked later with some other .o files to an executable.
So what you want to do is either compile the two files separately and link them later. like this.
gcc -I"/Home/Documents/ctests/" -c a1.c
gcc -I"/Home/Documents/ctests/" -c a2.c
gcc -o myprogram a1.o a2.o
Or just compile and link at the same time.
gcc -I"/Home/Documents/ctests/" a2.c a1.c -o myprogram
And then run your program like
path_to/myprogram
Compile everything, and link it together.
If all files are in one directory, this should work:
gcc a1.c a2.c -o myapp
When you want to create separate object files, do this:
gcc -c a1.c a2.c
Then you can then link together to create an application:
gcc a1.o a2.o -o myapp
Your gcc command should be like this
gcc -I/Home/Documents/ctests/ -o a1.out a1.c
and you have to include a1.h and a2.h header file in your a1.c like this
#include "a1.h"
#include "a2.h"
If you are calling some function from a2.c in your a1.c then you have to build your program in this way
gcc -I/Home/Documents/ctests/ -o a1.out a2.c a1.c