POV-Ray : Newsgroups : povray.off-topic : Unix shell : Re: Unix shell Server Time
3 Sep 2024 11:29:04 EDT (-0400)
  Re: Unix shell  
From: Warp
Date: 27 Jan 2011 10:26:22
Message: <4d418e9d@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> #2: You can compile a C++ program with

>    g++ program.c++

> However, for reasons beyond my comprehension, the result is always named 
> "a.out". You can tediously fix this using the -o option.

  How else do you suggest the binary be named? "The same as the source
file" is not a good answer because there may be (and often is) more than
one source file. You can easily compile a multi-sourced program with
"g++ *.cc". The -o parameter exists to tell the compiler the name of
the binary.

  Anyways, if you find yourself compiling the same program again and again,
that's exactly what makefiles are for, so you can simply write "make".

> Alternatively, 
> you can write a makefile:

>    prog1: prog1.c++
>      g++ prog1.c++ -o prog1

>    prog2: prog2.c++
>      g++ prog2.c++ -o prog2

>    prog3: prog3.c++
>      g++ prog3.c++ -o prog3

> Is there any way of automating this absurd tedium?

  A makefile is, basically, what other SDKs call a "project" file. You can
specify dependencies between files and rules on how to build files from
other files (the idea, as with "project" files in other SDKs, is that files
are built only if their source files change rather than every time).

  Writing a makefile by hand can be somewhat tedious, but you only have
to do it once. (Also, like most "project" files, it has a lot of flexibility.
Makefiles are not exclusively used to compile programs, but can be used for
a lot of other things where files are created from other files, or simply
programs are run based on certain rules.)

  Gnu make offers some shortcuts which you can use to abbreviate some things,
such as for example:

myprogram: source1.cc source2.cc source3.cc
	g++ $^ -o $@

  Of course that rule is incomplete in that if any of those source files
depends eg. on a header file, it won't take that into account (in other
words, if you change the header file, the program will not be recompiled).

  If you simply want it to recompile the program every time you run make,
you can "trick" make to do it by giving a rule which is named differently
from the resulting file, and leaving the conditions out, like:

all:
	g++ source1.cc source2.cc source3.cc -o myprogram

  (This works because there is no file named 'all' in the current directory,
so make will try to "build" it by running the command. Since the command
doesn't create it, it will do so also the next time you run make, and so on.)

  Of course this is good only if you really want to recompile everything
every time.

  A full-fledged makefile would build object files from each single source
file, and then link those object files into the final binary. This allows
compiling only those object files that really need it, so if there are
many source files, it will speed up compilation.

  Of course the rules for this to work become very complicated, and nobody
in their right minds would write them by hand. There exist tools to
automatically create a makefile from a bunch of source files (think
automake is such a tool), or you could use gnu make in conjunction with
gcc's dependency-generation features to do it with them. I use this
generic makefile a lot for this exact purpose. Simply add it inside the
directory where your source files are, and 'make' will do the rest. (The
only defect is that if dependencies change, this will not notice it. You'll
have to remove the .dep file and it will start working again.)

#------------------------------------------------------------
# List source files (not headers!) and binary name:
SOURCES=$(wildcard *.cc)
BINARY=programname

# Set up compiler and compiler options:
CXX=g++
LD=g++
CXXFLAGS=-Wall -Wextra -pedantic -ansi -O3
LDFLAGS=-s
LDLIBS=


# --- No need to modify anything below this line ---
all: .dep $(BINARY)

$(BINARY): $(SOURCES:.cc=.o)
	$(LD) $^ -o $@ $(LDFLAGS) $(LDLIBS)

clean:
	rm -f .dep $(BINARY) $(SOURCES:.cc=.o)

.dep:
	g++ -MM $(SOURCES) > .dep

-include .dep
#------------------------------------------------------------

-- 
                                                          - Warp


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.