How does my program run without including necessary .c files? - c

I am coding in C and in an attempt to organize my program and make it cleaner, I took all the functions out of main.c and put them in their own .c files which all include the header.h. I forgot to include all the .c files in my main.c and when I compiled the program, it still ran perfectly! How is this possible? Do you not need to include .c files that are in the same folder? Should I still include the .c files anyway to be safe?

You can have any number of c files you want, at compile time object files are generated and then linked togaether making the executable binary.
While including the c files in your main.c could work, it's not the appropriate way to split the program in different files, the correct way is to compile all the files into an intermidiate represantation called Object Files, and then the linker links them all togaether to make the executable binary.
So compilation goes like this
file1.c -> file1.o
file2.c -> file2.o
file3.c -> file3.o
file4.c -> file4.o
.
.
.
.
and then a linking stage which takes all the files
file1.o file2.o file3.o file4.o ... -> executable-binary-file
You could also pass all the c files to the compiler at once.

You're not supposed to include the other .c files in main.c
A C compiler will compile each .c file into .o files, separately.
And then it's the job of the linker to put the resulting objects files back together in a single executable.

Related

Is there a way to automatically find which files are compiled into a library using cmake/make?

I have a C library which I am using in a project. It consists of .c and .h files in src and include directories. I wrote a CMakeLists.txt file that generates a Makefile which compiles library.so.
The thing is, the library also includes .c files for tests, compatibility headers for other operating systems, and other files which I don't actually use. I would like to determine which src/header files are actually compiled into the .so library. Is there a way to do so automatically, based on CMakeLists.txt or Makefile, without going through and examining each file?
If you are using gccthen you can trick the compiler into telling you which source files it used by generating the dependency information for the next make run. If I am right, the necessary flags are:
-MT $# -MMD -MP -MF $(AUTODEP_DIR)$(notdir $#).d
This should produce for foo.cpp a file foo.o.d which contains target-prerequisites lines like:
foo.o : foo.cpp bar.hpp baz.hpp
foo.cpp :
bar.hpp :
baz.hpp :
where the line with the object file as target (the file before the :) displays what got used as C/C++ source in the compile run (all files after the :). Starting with the list of .o files which are in the libary, this should give you the exact list of files that you are looking for. It requires a bit of scripting but doesn't look too complicated.
clang and other compilers of course have their own, maybe differing set of flags but it shouldn't be too hard to pick them.

How to use functions in a package that is written in C in a different location

I am trying to use a linear algebra package called hnfprof. I have done the installation with the given instructions and now its ready to use. Now I want to use some functions in hnfproj/src/lift/lift.c file. I want to create my own matrix examples and check outputs for each functions separately. I am not clear how to do this. (I know only basics of C language, creating .c files in a folder and running it in my Ubuntu terminal.)
I know that I should write a C file including this "#include <lift.c>" file name and creating a matrix in my file "main.c". I don't know how to include a file name in a different location. When I compile I can not use "gcc -o program main.c lift.c". My "main.c" file is in a different folder. I don't want to create any make file inside the package folder. So how I can just use the "lift.c" file inside my "main.c" file which is in a separate folder "Main" and create all executable make files inside "Main" folder?
If its difficult to give a answer, appreciate if you can suggest me some source to learn this. Thank you
No need to include lift.c directly in main.c, and you can call function in lift.c from main.
When it comes to compilation, you can use:
gcc -o program main.c file_location/lift.c
If you need other options, add them (most flags at the start; libraries at the end, after the source code). You can also compile each file to object code separately and then link the object files together:
gcc -c main.c
gcc -c file_location/lift.c
gcc -o program main.o lift.o
refer
Compiling multiple C files with gcc

GCC compiler multiple files issues

I have a compiled C file, called Hello.o. in Hello.o:
I have a main function
and a function called int myfunc().
I wonder if I were to create a new file, hello2.c that contains a main function as well, and declare myfunc at the top of hello2.c,
will i be able to compile hello2.c and link hello.o to it using a gcc command?
Thanks all in advance.
If you want to just use myfunc() in hello2.c you can try linking the two objects files using gcc.Declare the function in a header file Hello.h and include it in hello2.c and generate Hello.o and hello2.c before linking them together by
$ gcc -o output Hello.o hello2.o
I think this should help you
How do I link object files in C? Fails with "Undefined symbols for architecture x86_64"
Object files are linked completely, or not at all. So this won't work.
GCC adds all the files specified in the command line as .o to the binary. Then the libraries (.a) are used to find needed symbols.
If there are duplicate symbols, an error is reported. (It doesn't know which main).
If a library contains more than one .o file, it can ignore the .O files which are not required. These may have duplicates with the binary.

Makefile for Multiple .c and .h files

I am having a 1.c 2.c....n.c files and having its dependencies .h file also... i know to create make file for multiple c files.But i don't how to create make file for which the c files are linking to .h files. If i try the makefile which i know it will give error like
make: *** No rule to make target '2.h', needed by '2.o' .Stop.
and I don't need this type of makefile also.
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
This will be good for 4 or 5 files. But if I have a large number of files, what is the best solution?
You can link all your .h in the Makefile by this way :
Put all the .h in a same file (that we called "Include" for the exemple)
Add this in your Makefile : gcc *.c -I/path/Include -iInclude
Ps: Your way to compile your .c file is a bit strange.
Usually we use this:
SRC = 1.c
2.c
n.c
OBJ = $(SRC:.c=.o)
all: $(OBJ)
gcc $(SRC) -I/path/Include -iInclude (where path is the location of your file called "Include")
As long as I'm working with C, I never wrote make files that includes header files (.h) the header files are here to expose some of the data structure and methods, constants that are needed in other C modules.
You don't need to create rules for header files, all you have to do is build the .o objects then the liker will do the magic for you when you create the executable file.
If you need some help crating a make file you can explain here what you wanna build and I'll send you a hint.
Cheers.
If your header files are not in current directory and you included it in Makefile, Make starts looking for header files in default location but it is not able to find them in your case.
you should put 2.h header files in current directory to avoid this search.

Including c files leads to undefined references

When I include c files, I start to get undefined references to other functions. Then, I have to start including the c files that contain the functions. How do I get around this? The undefined references are referenced in the c files that I include, but since I am not actually including those files, I get undefined references.
Generally one includes ".h" files, not ".c" files.
If you call a function declared in a .h file, it is not sufficient to compile the starting C file to get a complete program -- you also need to link in the object files associated with the code that implements the declared functions. These might be in a library, in which case you need to link with that library.
You need to either compile all the files at once (gcc *.c) or compile each .c file into a separate object file and then link them all into the executable:
gcc -c main.c -o main.o
gcc -c helper.c -o helper.o
gcc -c other.c -o other.o
gcc *.o -o main
And within each .c file you should only ever include .h files.
What do you mean by including? Including via the #include preprocessor directive, or including as in adding them to your project.
You cannot get around the fact that all of the functions that are called (or, generally, externals symbols that are referenced) in your program either have to be included in that program, or have to exist in a library that is linked to the program, explicitly or implicitly.
Just keep adding the source files that are needed until all the references are resolved.
If you can't do that, then you may have some problem with the program or build. Either the program is incomplete (missing source files), corrupt (missing parts of source files), or you have included an inappropriate source file into the build (e.g. a source file which is needed when the program is compiled for Unix, but you're building for Windows) or incorrectly configured (so it is conditionally compiling some code for the wrong platform) or the program is simply not ported to your system (makes references to library functions you don't have).

Resources