compile multiple source file in c - 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.

Related

Does it matter whether a compiled C program ends in .o?

For a hello world program, hello.c, does it matter if I compile it to a file name ending in .o? Or is it just a convention? E.g. should I do this:
gcc -o hello.o hello.c
Or this:
gcc -o hello hello.c
In a Linux environment
The situation here is a bit confusing because there are two kinds of "object files" — those that are truly intermediate object files (the ones normally ending in .o), and final executables.
You can use a typical command-line C compiler in two ways. You can compile to an intermediate object file, using the -c option, and then "link" to a final executable as a second step:
cc -c -o hello.o hello.c # step 1
cc -o hello hello.o # step 2
Or you can compile and link in one fell swoop:
cc -o hello hello.c # step 3
In the first case, when you compile and link in separate steps, the extension .o for the intermediate object file is the very strong convention by which everybody knows that it is in fact an intermediate object file. Notice the difference between steps 2 and 3. In step 3, the way the compiler knows it has some compiling to do is the extension .c. In step 2, on the other hand, the extension .o tells it the file is already compiled, and merely needs to be linked.
(Footnotes: Actually the compiler might assume in step 2 that any unrecognized filename was an intermediate object file to be linked. Also, we're talking about Unix here. Under Windows, the conventional extension for intermediate object files is .obj.)
Also, as you may know, the extension .o is very much the default when compiling only. In step 1, it would have sufficed to just say cc -c hello.c.
The advantage to "separate compilation" is that it gives you a lot more flexibility. If you have a larger program, made from several source files, you could recompile everything, all at once, every time, like this:
cc -o program file1.c file2.c file3.c
But if you compile separately, like this:
cc -c file1.c
cc -c file2.c
cc -c file3.c
cc -o program file1.o file2.o file3.o
then later, when you make a change to, say, file2.c, you can take a shortcut and only recompile that one file. (This does come at the cost of some disk space, to keep all those intermediate .o files around, and some complexity and extra typing, which for larger programs you usually let a build program like make take care of for you.)
Another thing you can do is to compile the same file multiple ways. For example, I often find myself wanting to test a utility function in a "standalone" way. As an (unrealistically simple) example, suppose that file3.c contains a function to multiply a number by two:
int doubleme(int x)
{
return x * 2;
}
Suppose that, elsewhere in file1.c and file2.c, whenever I want to multiply an integer by 2, I call my doubleme function. (Obviously this is completely silly and unrealistic, but it's just an example.)
But suppose you want a way to test the doubleme function, in a standalone way. I will often do something like this. At the end of file3.c, I will add:
#ifdef TEST_MAIN
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int x = atoi(argv[1]);
printf("doubleme(%d) = %d\n", x, doubleme(x));
}
#endif
Now I can compile file3.c in two different ways. If I compile it normally, like this:
cc -c file3.c
then I get file3.o, containing the compiled version of the doubleme function, that I can link in when I build myprogram. Or, I can say
cc -c -DTEST_MAIN -o file3_test.o file3.c
cc -o file3_test file3_test.o
and then I can invoke things like
file3_test 55
to test out the function.
By convention extension (in linux at least) .o implies an Object File, not an executable. So, yes, you can use this extension, as in gcc -o hello.o hello.c, but it's misleading and a bad idea. Better to do gcc -o hello hello.c.
However, if you are building the object file (i.e. compile only, not link) you would use the -c option, as in gcc -c hello.c, which will create the object file hello.o.
(Just summarizing what's already in the comments.)
By convention extension (in linux at least) .o implies an Object File, not an executable. So, yes, you can use this extension, as in gcc -o hello.o hello.c, but it's misleading and a bad idea. Better to do gcc -o hello hello.c.

In multiple file programs and inclusion, how the function definitions get included into the main program?

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.

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.

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.

Compile multiple C files with make

(I am running Linux Ubuntu 9.10, so the extension for an executable is executablefile.out) I am just getting into modular programming (programming with multiple files) in C and I want to know how to compile multiple files in a single makefile. For example, what would be the makefile to compile these files: main.c, dbAdapter.c, dbAdapter.h? (By the way, If you haven't figured it out yet, the main function is in main.c) Also could someone post a link to the documentation of a makefile?
The links posted are all good. For you particular case you can try this. Essentially all Makefiles follow this pattern. Everything else is shortcuts and macros.
program: main.o dbAdapter.o
gcc -o program main.o dbAdapter.o
main.o: main.c dbAdapter.h
gcc -c main.c
dbAdapter.o dbAdapter.c dbAdapter.h
gcc -c dbAdapter.c
The key thing here is that the Makefile looks at rules sequentially and builds as certain items are needed.
It will first look at program and see that to build program, it needs something called main.o and dbAdapter.o.
It will then find main.o. However, to build main.o, it will need main.c and dbAdapter.h (I assume dbAdapter.h is included in main.c).
It will use those sources to build main.o by compiling it using gcc. The -c indicates the we only want to compile.
It does the same thing with dbAdapter.o. When it has those two object files, it is ready to link them. It uses the gcc compiler for this step as well. The -o indicates that we are creating a file called program.
GNU make should be what you're looking for.

Resources