C how to use library with multiple header tree - c

I am not understanding how I should compile with gcc the following .c and library.
example:
Files: "commons.h" and "commons.c" (the .c defines function etc...)
Files: "level1.h" and "level1.c", level1.c includes "commons.h"
Files: "level2.h" and "level2.c", level2.c includes "commons.h" and "level1.h"
I tried this and got "undefined reference to x" (where x is a function inside level1):
gcc commons.c -c -o commons.o (OK)
gcc level1.c -c -o level1.o (OK)
gcc level2.c -o level2.o (error, undefined reference to x)
I expect to have level2 to be execute, I will only execute this.
How should I compile? Which order? (an example with command line will help me understand)

Your last line should also use the -c flag in order to compile level2.c to an object file level2.o.
Afterwards the object files should be linked to create an executable, which is done via
gcc common.o level1.o level2.o -o my_executable
Alternatively you can directly supply all the source files to gcc without the -c flag, in which case it will perform all of the compilation and linking steps at once:
gcc common.c level1.c level2.c -o my_executable
Your error is currently caused, because you are instructing gcc without the -c option to compile and link the source file level2.c alone, but of course it can not be linked alone as it is missing symbols from the other source files.
The fact that level2.c contains main does not change anything about this. main is handled like any other function, only that it has a special meaning in the final executable as entry point.

Related

How to run an executable in C using a linker

Essentially I have
header.h, tree.c, main.c, and list.c
Can someone tell me how to execute this in my vi terminal. I know to run a solo c file it's gcc list.c ...., but I need these linked and the header included. I just don't understand the format for running them all together as an executable with a linker. I've included header in all the files, but main relies on list and tree, and vice versa.
Any help trying to compile and run these with gcc in the terminal would be a big help. Whenever I try, it keeps running them separately and I get a bunch of errors.
You can compile (not run) and link these files into an executable in one step by passing each of the .c files to gcc together and using the -o option to give the name of the executable:
gcc -o myprogram tree.c list.c main.c
Or you can compile each of them to object files using -c:
gcc -c tree.c
gcc -c list.c
gcc -c main.c
And then link the resulting object files:
gcc -o myprogram tree.o list.o main.o

compile multiple source file in c

I have written c program, Which has 3 file(.c ) , Main program has
two threads and one file has mysql connection function, One file has
thread functions definition. I don't know how to compile all these
codes, Normally I tried like this,
cc -pthread main.c
But if I compile like this I am getting error called mysql functions
are undefined But I have written thread as separate program and
mysql as separate program and complied individually , it complied
successfully and I got output. So please help me to compile my
project File names are,
main.c (2 threads are declared) functions.c (thread function
definition, and mysql func declared) db.c ( mysql function
definition)
please help to compile my code?
You have two basic options when compiling multiple .c files:
Option 1)
cc file1.c file2.c file3.c -o executable_name
Advantage: simple
Disadvantage: if all you change is one file you are recompiling all the files
Option 2)
cc file1.c -c -o file1.o
cc file2.c -c -o file2.o
cc file3.c -c -o file3.o
cc file1.o file2.o file3.o -o executable_name
Advantage: If you change one file you do not have to recompile everything
Disadvantage: Multiple commands (but you should use a Makefile at this point)
The -c flag tells the compiler to compiler but not link. You don't want to link as you have not compiled all of your files. The final invocation of cc links all the .o files into the executable executable_name
It is a little bit difficult to understand exactly what you need, but I can tell you from what you've stated that you'll need to include specific libraries in your compile statement you currently are not. Also, a -l flag needs to prefix your libraries.
Try something like this:
gcc -lpthread main.c functions.c db.c -o main $(mysql_config --libs)
To explain, mysql_config --libs returns all the configuration libraries needed to run mysql ddl inside your C program.
Given your updates on your file declarations I'm guessing you're a Java programmer. C is not Java. If you are declaring functions you are only going to use once in main.c you should put them inside main.c unless you need them to be portable.

using a method from another file without including it [duplicate]

This question already has answers here:
Why is #include <stdio.h> not required to use printf()?
(3 answers)
Closed 8 years ago.
I have two .c files which I compile over a makefile.
foo.c:
void foo()
{
printf("this is foo");
}
main.c:
#include <stdio.h>
int main()
{
printf("this is main\n");
foo();
}
the makefile looks like that:
all: main.o foo.o
gcc -o prog foo.o main.o
main.o: main.c
gcc -c main.c
foo.o: foo.c
gcc -c foo.c
So the question is:
how can foo.c use printf() without me including stdio.h AND how can main.c use the method foo() without me including foo.c.
My guess/research is that the makefile works as a linker. But I dont have prove for that and want to understand how this works excactly.
Correct me if I misunderstood something.
In the compilation phase, the compiler checks function calls against prototypes. Any function that lacks a prototype is assumed to return int and to accept any number of arguments.
If you turn up the warning level, gcc will warn you if a prototype is missing. You should add -Wall and you could also add -pedantic to get diagnostics on additional things the compiler think are suspicious.
If the compilation step succeeds, the compiler creates an object file which contains the compiled code and 2 reference tables. The first table is the export table. It contains the names of all functions and variables that are exported from the object file.
The second table is the import table. It contains a list of all functions and variables that are referenced, but where the declaration was missing.
In your case we have:
foo.o:
Export:
foo
Import:
printf
main.o
Export:
main
Import:
printf
foo
In the linker phase, the linker will take the list of imports and exports and match them. In addition to the object files and libraries you specify on the command line, the linker will automatically link with libc, which contains all functions defined by the c language.
In the makefile you can force the complier to include <stdio> or any other header:
From the docs:
-include file
Process file as if #include "file" appeared as the first line of the
primary source file. However, the first directory searched for file is
the preprocessor's working directory instead of the directory
containing the main source file. If not found there, it is searched
for in the remainder of the #include "..." search chain as normal. If
multiple -include options are given, the files are included in the
order they appear on the command line.
Just add -include filename.h in the GCC/compiler command line within the makefile.
The makefile is not a linker. It is input to make. The makefile just tells make what commands to execute under what conditions.
Your all target is running gcc in linking/linker mode gcc -o prog foo.o main.o.
The same way your foo.o and main.o targets are running gcc in compilation mode gcc -c foo.c.
For the record you can combine the two .o targets into just
%.o: %.c
gcc -c $^
which is, in fact, already a default rule in make so you need not include that rule at all.
Additionally your all target is not following bet make practices because it generates a file that does not match the name of the target. So you should use
all: prog
prog: main.o foo.o
gcc -o prog foo.o main.o
instead.
Though once again there make has you covered by default and so your entire makefile can be replaced by
all: prog
prog: main.o foo.o
and you should get the same results.

Compiling multiple C files with gcc

I have two files, main.o and modules.o, and I'm trying to compile them so that main.o can call functions in modules.o. I was explicitly told not to try #include module.o. I really don't know what I should be doing instead. I tried a few different versions of gcc (such as gcc -x c driver main.o modules.o), but nothing I get works: the compiler continuously returns
error: called object is not a function
The .o files are my source code files (I was instructed to put my source code in files with extension .o.) What do I do to compile this?
If you have your two source files, you can compile them into object files without linking, as so:
gcc main.c -o main.o -c
gcc module.c -o module.o -c
where the -c flag tells the compiler to stop after the compilation phase, without linking. Then, you can link your two object files as so:
gcc -o myprog main.o module.o
This is all perfectly normal behavior, you'll usually get your makefile to compile things separately and link them at the end, so you don't have to recompile every single source file every time you change one of them.
Talking about main.o "calling functions in" module.o is perfectly fine, but an .o file is not a source file, it's a compiled object file. If "put my source code in files with extension .o" actually meant "compile my source code into files with extension .o" then the situation would make a whole lot more sense.
You should define the functions that you want to call from modules.c into main.c into a header file, let us say modules.h, and include that header file in main.c. Once you have the header file, please compile both of the files together: gcc main.c modules.c -o output
Two additional notes. First, modules.o is an object file and it should not be included in a C source file. Second, we cannot have a C file have a .o extension. You should actually get an error when compiling a .o file. Something like:
$ cat t.o
int main() {
int x = 1;
return 0;
}
$
$ gcc t.o
ld: warning: in t.o, file is not of required architecture
Undefined symbols:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
$
program: main.o
gcc -o main main.c anotherSource.c
This works for me.
You should be including .h files which are "headers". So if your main file is using modules then you should include module's header file.

NVCC linking error in C and CUDA-C code

I'm working on an DNA Fragment Assembly program. The CPU-only version is built in C language using GCC and I'm trying to build a GPU version using NVCC.
Here is the makefile
all : clean FragmentAssembly.exe
FragmentAssembly.exe : Common.o Fragment.o ILS.o Consensus.o main.o
nvcc -pg -o FragmentAssembly.exe Common.o Fragment.o ILS.o Consensus.o main.o
Common.o : Common.cu
nvcc -pg -o Common.o -c Common.cu
Fragment.o : Fragment.cu
nvcc -pg -o Fragment.o -c Fragment.cu
ILS.o : ILS.cu
nvcc -pg -o ILS.o -c ILS.cu
Consensus.o : Consensus.cu
nvcc -pg -o Consensus.o -c Consensus.cu
main.o : main.cu
nvcc -pg -o main.o -c main.cu
clean :
rm -f *.exe *.o
As seen, the original .c files became .cu files for nvcc to compile them correctly.
All of the cu files contain includes of their corresponding files (Common.h for Common.cu, etc..) except for main.cu.
ILS.h contians definition of global variables p_instanceFragments and p_instanceLength
The problem is when compiling NVCC, for an unknown reason, I get the following errors :
Consensus.o:(.bss+0x0): multiple definition of `p_instanceFragments'
ILS.o:(.bss+0x0): first defined here
Consensus.o:(.bss+0x8): multiple definition of `p_instanceLength'
ILS.o:(.bss+0x8): first defined here
There is no real multiple definitions since the same code is built correctly using GCC. It looks as if ILS.h is getting included twice in nvcc, by ILS.cu and Consensus.cu. This is also not possible since I've wrapped all my header files with an #ifndef .. #define .. #endif statements to avoid multiple includes and infinite include loops.
Maybe something with the makefile commands ? or should I use gcc for linking ? Can you tell me how to deal with it ?
Regards,
After discussion: Here a description of what happened:
If you use gcc and you have two files (lets say f1.c and f2.c), and in both files you declare:
int myGlobalVariable;
Then the following will happen:
When compiling f1.c into f1.o, the object file will reserve space for myGlobalVariable.
When compiling f2.c into f2.o, the object file will also reserve space for myGlobalVariable.
When you link both object files together, the linker will detect that there are two variables called myGlobalVariable and will merge these variables together.
Now it seems the nvcc compiler/linker is not able to merge these variables.
The problem was, that the file ILS.h declares <some type> p_instanceFragments;. Because ILS.h is included into both ILS.cu and Consensus.cu, you get this variable twice and nvcc complains when it has to link the application.
The solution is to declare extern <some type> p_instanceFragments; in ILS.h and then to define <some type> p_instanceFragments; either in ILS.cu or Consensus.cu (not in both).
The question What are extern variables in C has a rather extensive answer explaining all of this in detail.

Resources