hey, I split my project into 3 files:
globals.h
assembler.c (contains main())
hasher.c
presently, I'm compiling them in 2 stages:
>gcc globals.h
>gcc *.c -o assembler
is there a way to do it in 1?
many thanks.x
hey, I split my project into 3 files:
globals.h
assembler.c (contains main())
hasher.c
presently, I'm compiling them in 2 stages:
>gcc globals.h
>gcc *.c -o assembler
is there a way to do it in 1?
many thanks.x
The proper way to do it to avoid problems is to put only variable declarations and function prototypes inside the header files. All function definitions (ie. the actual function body) should go in a .c file with the same name as the .h file. All .h files should have header guards, and all .c files that need those headers should include them.
At the command line then, you only need to compile the .c files.
As far as I know, one typically does not compile header files. You would do:
gcc -o assembler assembler.c hasher.c
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Alternately, you could create a Makefile, then type make and it does everything for you.
if i don't re-compile globals.h after a change, everything messes up, so I guess the best idea is the makefile, but i've never made on before...
what would my makefile contain, in this instance?
many thanks.x
If you have to manually compile a header file, you really messed something up.
This is a chicken-and-egg problem. The reason you have to compile the header file is because you are compiling the header file. With recent versions of gcc, if you attempt to compile a header file, it produces a "pre-compiled header," with extension .gch. If gcc sees a .gch file which corresponds to your header file, it uses it in preference to the header file.
So, because you did this ONCE, you now have to do it each time. Solution? Delete that stupid .gch file, and you'll no longer have to compile the .h.
EDIT: In case I didn't make it COMPLETELY OBVIOUS: NEVER compile .h files
Last edited by brewbuck; 05-01-2007 at 05:49 PM.
No way.... thats cool then, because that stupid globals.h.gch file is over 1mb in size!
I hope I'm not doing anything seriously wrong; my globals.h file contains 3 things; all the #includes and #defines that my *.c files need, the deftypes I use for lists, and all the function prototypes.
So presumably, I can now just delete that globals.h.gch file, and then compile my whole project with the line
>gcc *.c -o assembler
But I'm still interested in make files; don't you just have to type:
>make
and it re-compiles only what has been updated? That sounds like a time-saver! How do I make my makefile?
cheers.x
That sounds fine to me, though I would include the standard (and library, if you are using one) headers that are needed for the header, and include any other needed headers in the source files themselves. The idea is to avoid including headers in files that do not need them.my globals.h file contains 3 things; all the #includes and #defines that my *.c files need, the deftypes I use for lists, and all the function prototypes.
make is quite commonly used, so you probably can just search the Web and find some useful tutorial. There are other build tools available, of course, such as SCons (see my signature).and it re-compiles only what has been updated? That sounds like a time-saver! How do I make my makefile?
Last edited by laserlight; 05-02-2007 at 01:04 AM.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
I posted a fairly generic Makefile for C++ the other day. Here's a C version. This is much close to the one I actually use:
This Makefile should be immediately usable just by listing your .c and .h files in the locations indicated. You can adjust the optimization flags with OFLAGS, the debug flags with DFLAGS, the warning flags with WFLAGS (but please keep the warnings TURNED ON!), and the profiler flags with PROFFLAGS. If you don't know what something means, there is no need to change it.Code:CC = gcc PROFFLAGS = DFLAGS = -g WFLAGS = -W -Wall OFLAGS = INCLUDE = # Drop your include paths here CFLAGS = $(DFLAGS) $(OFLAGS) $(WFLAGS) $(PROFFLAGS) $(INCLUDE) LIBS = # Drop your library paths and libs here LDFLAGS = $(LIBS) $(PROFFLAGS) SRCS = # Drop your .c files here HDRS = # Drop your .h files here OBJS = $(SRCS:.c=.o) TARGET = a.out # Set your program name here .PHONY: all clean realclean all: $(TARGET) $(TARGET): $(OBJS) $(CC) -o $@ $^ $(LDFLAGS) clean: rm -f $(OBJS) rm -f $(TARGET) realclean: clean rm -f .depend .depend: $(SRCS) $(HDRS) $(CC) $(INCLUDE) -M $(SRCS) > .depend -include .depend
This Makefile will AUTOMATICALLY rebuild dependencies when your source code changes. This means it will always recompile the necessary files. Just say "make".
To clean up, say "make clean." This removes all objects and targets, leaving you with just the source code. "make realclean" does the same thing but in addition it deletes the dependencies file.
Another factoid... GNU make has a default target which you can use to build simple programs. If you program is entirely contained in a single .c file, say, program.c, you can just say:
It will automatically compile program.c to create "program." You don't need a makefile to do this.Code:$ make program
EDIT: One other very useful thing -- you can override the value of a variable directly on the make command. For instance, if you wanted to build with OFLAGS set to "-O2", you could set it in the makefile, or you could just do this:
Whenever you change the flags, it is a good idea to "make clean." If you don't, make won't see that the flags have changed, and it won't recompile anything.Code:$ make OFLAGS=-O2
EDIT EDIT: The indentation of the makefile is IMPORTANT. It won't work without it. The indentation MUST be done with TAB characters, not spaces.
Last edited by brewbuck; 05-02-2007 at 11:06 AM.