Thread: compiling source files and header file at once?

  1. #1
    Registered User 1jackjack's Avatar
    Join Date
    May 2007
    Location
    Bristol
    Posts
    4

    compiling source files and header file at once?

    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

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    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.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    As far as I know, one typically does not compile header files. You would do:
    gcc -o assembler assembler.c hasher.c
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Alternately, you could create a Makefile, then type make and it does everything for you.

  5. #5
    Registered User 1jackjack's Avatar
    Join Date
    May 2007
    Location
    Bristol
    Posts
    4
    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

  6. #6
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    If you have to manually compile a header file, you really messed something up.

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by 1jackjack View Post
    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...
    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.

  8. #8
    Registered User 1jackjack's Avatar
    Join Date
    May 2007
    Location
    Bristol
    Posts
    4
    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

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    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.
    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.

    and it re-compiles only what has been updated? That sounds like a time-saver! How do I make my makefile?
    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).
    Last edited by laserlight; 05-02-2007 at 01:04 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by 1jackjack View Post
    and it re-compiles only what has been updated? That sounds like a time-saver! How do I make my makefile?
    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:

    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 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.

    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:

    Code:
    $ make program
    It will automatically compile program.c to create "program." You don't need a makefile to do this.

    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:

    Code:
    $ make OFLAGS=-O2
    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.

    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.

  11. #11
    Registered User 1jackjack's Avatar
    Join Date
    May 2007
    Location
    Bristol
    Posts
    4
    genius, many thanks.x

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  2. Source file inclusion
    By sh3rpa in forum C++ Programming
    Replies: 7
    Last Post: 10-02-2007, 11:10 AM
  3. Class methods in header or source file?
    By TriKri in forum C++ Programming
    Replies: 13
    Last Post: 09-17-2007, 05:23 AM
  4. Linking header files, Source files and main program(Accel. C++)
    By Daniel Primed in forum C++ Programming
    Replies: 3
    Last Post: 01-17-2006, 11:46 AM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM