Calling methods from multiple C files without custom header files, Makefile Linking - c

This has gotten a bit lost in translation so I am going to be more precise:
we have classes recursion.c, fib.c, and countUp.c. from recursion.c we have to recursively call fib.c or countUp.c, decided by the input argument. I can't use header files and am only given that I must place prototypes:
int fib(int n);
and
void countUp(int n);
My Makefile
TAR = tar
COMPILER_FLAGS = -g -Wall -std=c99 -c
LINKER_FLAGS = -g -o
OBJS = recurse.o
C_FILES = recurse.c fib.c countUp.c
ASM_FILES = recurse.asm
TARGET_FILE = recurse
TARGET_TAR = PA5.tar
$(TARGET_TAR): $(TARGET_FILE)
$(TAR) -cvf $(TARGET_TAR) $(C_FILES) $(ASM_FILES) $(TARGET_FILE) Makefi$
recurse.o: recurse.c
$(C_COMPILER) $(COMPILER_FLAGS) $(C_FILES)
$(TARGET_FILE): $(OBJS)
$(LD_LINKER) $(LINKER_FLAGS) $(TARGET_FILE) $(OBJS)
where fib and countUp class methods must be called recursively. The recursive.c file is considered our c driver. Do not create or implement any header files OTHER than those that are standard c headers (stdio.h, string.h, etc.). When I try to run this I get:
make
gcc -g -o recurse recurse.o
recurse.o: In function `main':
(file root location)/recurse.c:43: undefined reference to `fib'
(file root location)/recurse.c:46: undefined reference to `countUp'
collect2: ld returned 1 exit status
make: *** [recurse] Error 1
Any clue what is going on.
Original Question:
I have multiple C files that I am combining into an executable. For example say I have math.c, the arguments are passed into it, and then if the input argument calls add it performs functions from add.c, if the argument calls subtract it will call functions from subtract.c, etc. The files are then compiled into a .o file, and then an executable is created. The issue I have is not being able to utilize header (.h) files. Is there any way to break into the separate classes or am I missing something? I really don't know exactly how to ask the question, jargon is pretty bad as far as C goes, sorry :(
I don't really get the idea of a driver I guess. (Not a device driver, she keeps telling us this is a c executable driver).

If I understood correctly, what I think you need to do is add the following prototypes above any of the functions you define in recursion.c. The prototypes will allow you to call these functions from within any function inside recursion.c (In fact, including a header file is akin to copy-pasting all of the prototypes defined in the file, as #Justin and #EdS already pointed out)
int fib(int n);
void countUp(int n);
int main() {
...
}
Then you need to make sure that your project file includes the files recursion.c, fib.c, and countUp.c - When you build your project, the linker will do its job and lookup the entry points in your compiled object files, and will proceed to assemble a single executable file.
What compiler are you using?

Including a header file is just a preprocessor directive to include the contents of that file at the location of the include. To achieve the same thing without a header file just copy and paste the code that you would have put in the header file into the top of each c file.
Of course this isn't very maintainable as if you want to change that contents you need to change it in many files, hence why header files exist in the first place.

Since this is homework and considering the fact that you have told us that A) You have no header files to use, and B) you have not been instructed to utilize the extern keyword, it seems to me that your only choice is to include the .c files themselves:
#include "add.c"
#include "subtract.c"
/* etc... */
int main()
{
// use functions defined in "add.c", "subtract.c", etc.
}
Note that this is bad form as you are including the implementation instead of the interface and likely pulling in a bunch of stuff you don't want or need. If that doesn't answer your question then there is something, some instruction from your teacher, missing in the question.

Related

How to combine assembly functions in .h file?

Might be a duplicate but i wasn't able to find a answer for my question.
Usually if you want to import multiple functions from different c files in one main class, one would make a .h file and list up all functions from the .c sources.
My problem is, that all functions are wridden in .asm files. I used extern void asmFunc(int i, char c); to use the function in further code, but they become more and more and i don't want to end up with 200 of those extern lines at the beginning of my main. How can i create a library.h with all assembly functions so i can just write #include "library.h" at the beginning of my main class?
EDIT:
I think i didn't give enough specific information:
I use MINGW gcc and NASM to compile c and asm files
I have to compile all files to .o first so i can match them
The first answer i got didn't work because my compile chain is a bit complicated thanks to the restrictions i have on Windows (i want Linux back)
It looks like this:
I got a folder containing three folders with seperated library-like structures: bwt (basic window toolkit), io and std (stuff like strlen)
They are compiled into bwt.o io.o and std.o.
Now i want to make a .h file for each of them so i can #include "bwt.h" in all kernel classes which need them. How do i get gcc to realize, that all functions in bwt.h are defined in bwt.o?
Since you have a .o file, it doesn't matter that the source for those routines is assembly. As long as you know how to call them as C functions that's what matters.
So put all of your extern declarations for the assembly functions in library.h, then #include "library.h" in your main file. Then you can link them.
gcc -c main.c
gcc -o program main.o asmfunctions.o
You can:
Make a file
Save the file as library.h (same folder as your C file)
Put your extern declarations* in the file
Add #include "library.h" in your C file
#include is literally copy-paste. You can put some code into another file, and then you can #include that file, and the compiler pretends you wrote the code in the main file directly. That's how it works.
* by the way, you don't need to write extern when declaring functions - only variables.

Makefile, better understanding rules

Reading the official documentation
A prerequisite is a file that is used as input to create the target. A
target often depends on several files.
If my source file already includes the header, should I list the header in the rule?
src.c
#include <stdio.h>
#include "myheader.h"
int main()
{
printMessage();
return 0;
}
myheader.h
void printMessage()
{
printf("a message to screen\n");
}
makefile
src : src.o
cc -o src src.o
src.o : src.c
cc -c src.c
If I add myheader.h in the prerequisite it changes nothing, the same message is printed to screen. If a header is explicitly included, should it appear in the prerequisite?
The header file should be included in the dependency list.
The first time you use make to build your program, it will compile just the same whether you include myheader.h as a dependency or not. The difference is what happens when one of the files changes.
If you run make again without changing anything, it will say that "src" is up to date and won't compile anything. However, if you were to modify myheader.h and you didn't include it as a dependency, then make will say that the target is up to date. It doesn't look at the source file to see what files it includes. The make utility doesn't know anything about C or C++ source code (or any other source code). It looks only at whether the given files have changes without looking at their content.
When you include myheader.h as a dependency, if you later modify that file then running make will rebuild the program.
If you want to know all the non-system header files that a given source file depends on, you can run gcc with the -MM option. This will output a make rule listing the header dependencies of a source file.
For example, if you run gcc -MM src.c, you'll get the following output:
src.o: src.c myheader.h
You can then include that in your makefile.
Yes, you should.
The make program uses the list of files to figure out if a dependency changed and the the target should be rebuilt as a result. It needs you to specify that dependency explicitly.
It does not see the inclusion, it only sees the rules you specified. So there is a theoretical possibility that you change the header in a way that may require a re-compilation of src.o, but make will not know you did that unless you tell it to watch out.

Contiki: undefined reference to a function defined in a separate source file

I am writing a program using the Contiki operating system.
I have the remote_firmware.c file and a folder called parser with the files parser.h and parser.c where I wrote the method void test(). I included parser.h in remote_firmware.c with:
#include "parser/parser.h"
The Makefile looks like this:
CONTIKI_PROJECT = remote_firmware
all: $(CONTIKI_PROJECT)
#UIP_CONF_IPV6=1
CONTIKI_WITH_RIME = 1
CONTIKI = $(HOME)/contiki
include $(CONTIKI)/Makefile.include
When I try to build this the Error occurs:
undefined reference to 'test'
I am aware that the Makefile needs to know about parser.h, but I do not know how. I tried several solutions which were proposed here but I guess I did something wrong. Maybe somebody of you know what to do?
Thank you a lot.
Where is your source file located? Try adding the source file name to the PROJECT_SOURCEFILES preprocessor variable (i.e PROJECT_SOURCEFILES+=parser.c) and adding the location of the source file to the CONTIKIDIRS preprocessor variable (i.e CONTIKIDIRS+={Directory}).
If parser.c depends on a lot other C files you might want create an C library archive first and then adding the library to your project by adding the name of the library to the TARGET_LIBFILES variable.
The error undefined reference to test is an error from the linker not the compiler. It has nothing to do with including a header file. It means when you linked the executable you didn't include parser.o

C - How are c source files incuded without an include statement

I've taken the plunge and am learning C. It's been a pretty good but manageable learning curve coming from a scripting (php, perl) background with only a little bit of C#.
I've used the web-site "Learn C The Hard Way" and am so far grasping reasonably well (I think) but I can't understand this part of one of the exercises:
http://c.learncodethehardway.org/book/ex19.html
He created four source files - object.h, object.c, ex19.h, ex19.c
But I don't understand how the object.c file is included.
The main function is located in ex19.c, and it has the line
#include "ex19.h"
File ex19.h has the line
#include "object.h"
But object.h makes no reference to including object.c. Interestingly object.c contains the line
#include "object.h"
Is there some sort of implied include where if you include the header file, it will automatically include the c source code of the same name?
This is the job of a separate program called the linker. In C, source files need access to the header files of other C source files so that they can see information about what functions, types, and variables are defined by that second C file that the first file might want to use. Each C file is then compiled independently of the rest. The output of the compiler is an object file.
To build a final program, a second program called the linker comes in and combines all the object files together into the overall executable. This program is tasked with taking the implementations of all the different C files and cross-referencing them against one another so that each time one C file references a function or variable in a different C file, that reference can actually be made to the appropriate object.
This is why you don't need to include .c files. Once a source file has a header, it knows enough about the other file in order to use the functions it provides for the compiler to verify that it's using them correctly. The linker then handles of the job of actually making the cross-references. You can think of the compiler as a program that checks to see that if the functions are defined, then the program would work. The linker then actually checks to make sure that those functions are defined in the first place and sets up the appropriate links in the executable.
Hope this helps!
Object.c is not included.
It's compiled as it's own unit and it includes object.h
See the make file:
CFLAGS=-Wall -g
all: ex19
ex19: object.o
clean:
rm -f ex19
ex19: object.o tells you that object.o must be created before ex19 can be built, and this is picked up by default from make file as an object.c exists.
So this make file says
to build all you need ex19, to get ex19 you need object.o, and the to create object.o the makefile picks up object.o built from the object.c
From the page you reference:
make can't see anything in the file for object.o, but it does see an
object.c file, and it knows how to turn a .c into a .o, so it does
that.
The entire logic lies in the makefile and an intelligent compiler. The final binary created has an object file named as object.o which will ideally contain all the function definitions defined in object.h file. It is the linker which links the functions declared in .h file with the definition which are available in .o file.

function header and implementation in different files C

How do you have a header file for a function and the implementation of that function in different files? Also, how do you have main in yet another file and call this function?
The advantage is so that this function will then be an independent component which can be reused, right?
This is best illustrated by an example.
Say we want a function to find the cube of an integer.
You would have the definition (implementation) in, say, cube.c
int cube( int x ) {
return x * x * x;
}
Then we'll put the function declaration in another file. By convention, this is done in a header file, cube.h in this case.
int cube( int x );
We can now call the function from somewhere else, driver.c for instance, by using the #include directive (which is part of the C preprocessor) .
#include "cube.h"
int main() {
int c = cube( 10 );
...
}
Finally, you'll need to compile each of your source files into an object file, and then link those to obtain an executable.
Using gcc, for instance
$ gcc -c cube.c #this produces a file named 'cube.o'
$ gcc -c driver.c #idem for 'driver.o'
$ gcc -o driver driver.c cube.c #produces your executable, 'driver'
Actually you can implement any function in header files for better performance(when implementing libraries for example) as long are not referenced to a specific object(actually it won't compile that).
By the way even with that way, you have separate interface and implementation ;)
Of course you will have include gurads in you header files to avoid "multiple definition" errors.
In C/C++, non-inline functions should be defined only once. If you put function defination
in header files, you will get "multiple defination" link error when the header file is included more than once.

Resources