I have two .c files that both have mains. One of the files has a function that I would like to use in the other main. Is it possible to reference this other function without copying and pasting it into the other .c file?
No you don't need to copy and paste, suppose you have this
program-one.c
First program.
#include "common.h" /* This should be implemented */
int main(void)
{
do_program_one_stuff();
common_function();
return 0;
}
program-two.c
Second program.
#include "common.h" /* This should be implemented */
int main(void)
{
do_program_two_stuff();
common_function();
return 0;
}
You need a third .c file and a .h file, like this
common.c
Common Functions Implementation.
void common_function()
{
/* Do it here */
}
common.h
Common Functions Header.
void common_function();
You now can compile a single binary for each program consisting of two files, the program specific .c file and common.c.
The right way to do it is to have a Makefile and generate object code first, and then link the object files togeather, thus compiling each file only once.
Makefile
This is a GNU make Makefile using gcc as the compiler.
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g3 -O0 # enable debug symbols and warnings
LDFLAGS = # linker flags here ...
OBJ = common.o program-one.o program-two.o
all:
$(CC) $(LDFLAGS) common.o program-one.o -o program-one
$(CC) $(LDFLAGS) common.o program-two.o -o program-two
%.o: %.c
$(CC) $(CFLAGS) -c $<
clean:
#rm -fv *.o program-one program-two
EDIT: in response to your comment I would suggest the following
#define main ignore /* Or whatever name you want */
#include "the-student-implementation.c"
#undef main
int main(void)
{
/* This would be your `main()' */
return 0;
}
The best solution is what iharob suggested, but if for some reason that isn't possible, you could surround the main() in the file containing the common function with #ifdef USE_MAIN, then only define the USE_MAIN identifier in the command to build that project. When you build the other project that doesn't have USE_MAIN defined, the preprocessor will cause the second main() to be skipped, so the compiler won't be confused.
But unless this is really needed, I highly recommend splitting this into three files: main1.c, main2.c, and common.c/common.h
Related
I have a problem including my own library.
I have created some functions in a few archives .c,
after that i have created the header file .h,
but when i try to compile a main.c that call a function that was in my own lib
i must to type gcc ownlib.a main.c -o prog.out and include the lib ownlib.a archive
as a parameter of gcc.
In this case i was trying to call my own strlen() called ft_strlen() function that is in my own lib.
I know when i compile any program using a function that is in a compiler library i only must
include the header in the code for example: #include <string.h>,
but when i call my own function i add #include "ownlib.h".
If i compile the main.c calling system function strlen() i have to compile only the main.c
archive and it works.
When i create a lib with my own ft_strlen() and in the main.c i include my own lib
#include "ownlib.h" it doesn´t work if i do this gcc main.c -o program.out
but it works if i add my lib archive like this gcc main.c ownlib.a -o program.out
I want to know why when i use a system library function i don´t need to compile with the library archive,
for example gcc main.c string.c -o program.out,
only whith the #include <string.h> it works,
and why i must to include my ownlib.a in the compiation gcc libft.a main.c -o program.out.
I don't know if I explained myself well
LIBNAME = ownlib.a
HEADERNAME = ownlib.h
SRCS = ft_strlen.c
OBJS = $(SRCS:.c=.o)
CC = gcc
CFLAGS = -Wall -Wextra -Werror
AR = ar
ARFLAGS = -rcs
$(LIBNAME): $(OBJS) $(HEADERNAME)
#$(AR) $(ARFLAGS) $(LIBNAME) $(OBJS)
all: $(LIBNAME)
clean:
$(RM) $(OBJS)
fclean: clean
$(RM) $(LIBNAME)
re: fclean all
%.o: %.c $(HEADERNAME)
#${CC} ${CFLAGS} -c $< -o ${<:.c=.o}
.PHONY: all clean fclean re
one of the functions is like this:
#include "ownlib.h"
size_t ft_strlen(const char *str)
{
int i;
i = 0;
while (str[i] != '\0')
i++;
return (i);
}
Th main function is:
#include <stdio.h>
#include "ownlib.h"
int main(void)
{
char *str;
str = "How many characters";
printf("%i", ft_strlen(str);
return (0);
}
If i compile gcc main.c -o program.out don´t know what is ft_strlen()
Thanks so much
I have 3 files in this program, lab4.c, functions.h, functions.c
The lab4.c calls a function multiply(), whose prototype is in functions.h and is defined in functions.c. Multiply then used multiple other functions from functions.c. The only includes I have for this is in lab4.c including functions.h, do I need more? The problem I am having is described below
lab4:
#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
int main(void) {
...
}
functions.h:
#ifndef FUNCTIONS
#define FUNCTIONS
void divideByPowerOf2(unsigned int* a, int power);
void multiplyByPowerOf2(unsigned int* a, int power);
...
#endif /* FUNCTIONS */
functions.c:
void divideByPowerOf2(unsigned int* a, int power){
*a >>= power;
}
void multiplyByPowerOf2(unsigned int* a, int power){
*a <<= power;
}
...
Currently, my makefile looks like this:
Makefile:
#Makefile
all: lab4
lab4: lab4.o functions.o functions.h
gcc -Wall -o lab4 lab4.o functions.o
lab4.0: lab4.c
gcc -c lab4.c
functions.o: functions.c
gcc -c functions.c
now this will recompile when I change the header file, but the changes dont actually take effect. For example, if I change the header file to
#ifndef FUNCTIONS
#define FUNCTIONS
void divideByPowerOf2(unsigned int* a, int power);
//void multiplyByPowerOf2(unsigned int* a, int power);
...
#endif /* FUNCTIONS */
the program still works just fine. Im assuming I may have messed up linking the files with includes and everything, as that usually confuses me. For example, does functions.c need to refer to anything? and does functions.h need any kind of reference to the .c files? How do I get this to work properly so that if I change the header file, it recompiles and actually uses the new header
Thanks for any help!
First, there's a typo here:
lab4.0: lab4.c
should be
lab4.o: lab4.c
then, your function.h should be on the source => object dependency lines, not on the object => executable line, else, if you change the .h file, it just re-links without rebuilding the .o files: it changes nothing.
Moreover, it's good to use -Wall, but you have to use it when you compile your files, not when you link the executable, or you'll miss the actual compilation warnings (-Wall during the link phase only is pretty useless).
For instance, the -Wall flag would show you that commenting a prototype generates an "implicit declaration" warning (which can lead to an improper call/return values of a function). It's even more effective with -Werror, which turns warnings into errors, so you cannot ignore warnings.
Here's how your makefile should look like:
all: lab4
CFLAGS = -Wall
lab4: lab4.o functions.o
gcc -o lab4 lab4.o functions.o
lab4.o: lab4.c functions.h
gcc $(CFLAGS) -c lab4.c
functions.o: functions.c functions.h
gcc $(CFLAGS) -c functions.c
note that if you only have 2 source files and they're small enough, you could even not use the make file by just running:
gcc -Wall -o lab4 lab4.c functions.c
in a script. That's not adapted if you have too many / big source files, because it rebuilds everything everytime.
There are 4 files:
helper.h //contains the signatures of functions in helper.c
helper.c //implements the signatures in helper.h
file.h //has all the includes needed to run file.h
file.c //this file includes file.h and helper.h
In file.c, I need to use the function that is defined in helper.c in my main function. However, file.c is saying that there is an undefined reference to 'func_found_in_helper.c'
Is this structure correct?
Yes, provided file.c contains
#include "helper.h"
and when building your program you link together helper.o and file.o.
You also need to ensure you compile each of the files with -c so that the compiler only compiles (and not links); do the link later with all the object files.
Here's a working example (I don't actually need a main.h but if you have one of those, #include it from main.c):
main.c
#include <stdio.h>
#include <stdlib.h>
#include "helper.h"
int
main (int argc, char **argv)
{
test ();
exit (0);
}
helper.c
#include <stdio.h>
void
test ()
{
printf ("Hello world\n");
}
helper.h
void test ();
To compile
gcc -Wall -Werror -c -o main.o main.c
gcc -Wall -Werror -c -o helper.o helper.c
To link
gcc -Wall -Werror -o test main.o helper.o
In a Makefile
test: main.o helper.o
gcc -Wall -Werror -o test main.o helper.o
%.o: %.c
gcc -c -Wall -Werror -o $# $<
clean:
rm -f *.o test
To run
$ ./test
Hello world
It's a bit difficult to tell what else might be wrong without the program; my guess is you simply forgot the -c flag to gcc, or forgot to link in helper.o.
undefined reference to 'func_found_in_helper.c'
That's a little odd, as it suggests you have tried to call the function using the '.c' extension, rather than just the function name. Maybe the '.' is just a typo in the question ?
Also a linker will flag an undefined symbol, so it may also be that you have not told the linker where to find helper.o ( the helper.c file compiled to the an object file ). The compiler will start the linker automatically. Did you compile helper.c first ?
Is it possible to link two C files using makefile which calls each other function but both have a main function of their own.
e.g:
C1.c uses function f() from C2.c.but both have main function and I want the main in C1.c to be considered as main only.
FILES.o=set.o hash.o printnfa.o input.o nfa.o dfa.o terp.o minimize.o defnext.o print_ar.o pairs.o squash.o signon.o print.o lex.o assort.o prnt.o printv.o bintoasc.o ferr.o onferr.o fputstr.o pchar.o driver.o searchenv.o hashadd.o esc.o
PROGRAM= Lexer
INC := -I./debug.h -I./global.h -I./stack.h -I./set.h -I./hash.h
CFLAGS=-DMAIN
all: ${PROGRAM}
${PROGRAM}: ${FILES.o}
${CC} -o $# ${CFLAGS} $(INC) $^ ${LDFLAGS} ${LDLIBS}
Now terp.c has a main and lex.c also has a main. I want only the main for lex.c to be considered.
This will be specific for the linker you use. On Linux you can pass the --allow-multiple-definition flag to the linker in order to use only the first symbol in case of multiple definitions:
${PROGRAM}: ${FILES.o}
${CC} -Xlinker --allow-multiple-definition -o $# ${CFLAGS} $(INC) $^ ${LDFLAGS} ${LDLIBS}
This will omit all errors about duplicate symbols and cause the linker to ignore any redefinitions. Make sure that the object file containing the symbol you wish to use comes before any redefinitions in the list.
The short answer... NO ... it is NOT possible
First of all I would recommend that you refactor the code so that you don't have functions that will be used by many programs in the same file as a main function.
Any way, here is an example on how to use the pre-processor to include only one of the main functions.
We have two source code files both with a main function plus one other function, foo() in file1.c and bar() in file2.c. foo() and baa() are called from both of the main functions.
By changing the MAIN_ALT value in the Makefile we can switch between the main functions:
Use the main function in file1.c:
DEFINES += -DMAIN_ALT=1
Use the main function in file2.c:
DEFINES += -DMAIN_ALT=2
Makefile:
OBJS = file1.o file2.o
DEFINES += -DMAIN_ALT=1
CFLAGS += -Wall $(DEFINES)
prog:$(OBJS)
$(CC) $(CFLAGS) -o $# $^
file1.c:
#include "stdio.h"
#include "def.h"
void foo(){
printf("From foo\n");
}
#if MAIN_ALT == 1
int main(){
printf("Main in file1.c\n");
bar();
foo();
return 0;
}
#endif
file2.c:
#include "stdio.h"
#include "def.h"
void bar(){
printf("From bar\n");
}
#if MAIN_ALT == 2
int main(){
printf("Main in file2.c\n");
bar();
foo();
return 0;
}
#endif
def.h:
#ifndef __DEF_H__
#define __DEF_H__
void foo();
void bar();
#endif
I recently asked this question about compiling multiple files in C so that a file main.c can reference a file modules.c. The answer ended up being to make the modules file into a header file and having main import it.
I have now been told that this is an incorrect way to do it, as C supports modular compilation. My Makefile is below, and this is supposedly supposed to be correct, but I receive errors for each function call in main.c -- warning: implicit declaration of function X.
What do I need to do to compile this correctly, with two .c files rather than a .c and .h file? The main.c file has a main() function that needs to be able to call the functions in modules.c.
Makefile:
#################################################################
# Variables
# -- allows C-source and assembly-source files mix. Again, the
# -- indented lines start with a TAB(^I) and not spaces..
#################################################################
CFLAGS = -g -Wall -Werror
LDFLAGS =
CC = gcc
LD = gcc
TARG = driver
OBJS = modules.o main.o
#################################################################
# Rules for make
#################################################################
$(TARG): $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) -o $(TARG)
%.o: %.c %.s
$(CC) $(CFLAGS) -c $<
clean:
rm -f *.o *˜ $(TARG)
print:
pr -l60 Makefile modules.c main.c | lpr
#################################################################
# Dependencies -- none in this program
#################################################################
You've already gotten feedback about using GCC and Makefiles, and it's been noted that the typical way to accomplish your task would be two .c files and one .h file. But it's not required to have a .h file if you use function declarations (which is arguably simpler, just less maintainable and useful), as demonstrated by the following below example.
main.c:
void moduleFunc1(int); // extern keyword required for vars, not for functions
int main()
{
moduleFunc1(100);
return 0;
}
module.c:
#include <stdio.h>
void moduleFunc1(int value)
{
printf("%d\n", value);
}
To compile:
gcc main.c module.c
Edit: After having looked at the assignment you linked, my best guess is actually still that function declarations are what you are looking for. To quote from the assignment, under "Others", #7:
A function should be declared in the module/function where
it is called and not in global scope. Say A calls B and C does
not call it then B should be declared in A only.
In my example, the function declaration is in the module where it's called and seems to meet the A-B-C example. (The confusing part is the global scope comment, but I wouldn't say that the function declaration's scope is global. Observe that if you move the declaration below main(), for example, it messes things up. I haven't found something strictly authoritative for this point, though.)
Having read the assignment, could your instructor possibly mean the following?
main.c:
#include <stdio.h>
int main() {
int plus(int a, int b); /* declaration */
printf("%d ", plus(4, 5));
exit(0);
}
module.c:
int plus(int a, int b) {
return a + b;
}
gcc -Wall -Wextra main.c module.c
The thing is though, that plus() is available in the global namespace. So I am a bit lost.
Just an aside:
3. int next = 234;
printf("%6d ", next);
will print value of next, right justified in 6 columns
6. Use separate statements for declaration and initialization
of a variable as:
int xval;
xval = 100;
Do as I say, not as I do!
You can do this a few ways, but regardless of which you choose, if main.c calls functions from module.c, then main.c must #include a header which declares prototypes for those functions.
The first and simplest way is to just do this:
gcc -Wall -g main.c module.c -o myprogram
The second and more ornate way is to build module.c first as an object file. The primary purpose of this method is to save time when developing/debugging/compiling large programs with multiple parts -- rather than having to recompile the whole thing, you can just recompile the parts the have changed. It also allows you to easily mix and match parts. This is easiest to do with a makefile:
myprogram: main.c module.o
CC $(CFLAGS) main.c module.o -o myprogram
module.o:
CC $(CFLAGS) -c module.c
Notice the "myprogram" target from the makefile works with (prereq) module.o whereas the plain gcc method works with module.c.
If, as per your assignment, you can't use a header or global declarations, you can declare prototypes inside functions:
void somefunc () {
char *whatever (int x); // prototype
printf("%s\n", whatever(12));
}
Is fine, and presuming whatever() is defined somewhere, will work when you compile and run it.