using a shell script to compile your C programs

P

pereges

Do you see anything wrong about this method ? For eg. I write a shell
script a.sh containing :

cc -o test file1.c file2.c file3.c

and then execute the shell script ( sh a.sh) to compile and create the
executable. What is the difference between this method and writing a
make file ?
 
J

Joachim Schmitz

pereges said:
Do you see anything wrong about this method ? For eg. I write a shell
script a.sh containing :

cc -o test file1.c file2.c file3.c

and then execute the shell script ( sh a.sh) to compile and create the
executable. What is the difference between this method and writing a
make file ?
Not really topical here, try comp.unix.programmer

But: using a makefile would ensure that the target gets build afresh
whenever the source has changed (i.e is newer than the target), a shell
script would always compile, unconditionally, regardless whether it is
acctually neccessary.

Bye, Jojo
 
S

Spiros Bousbouras

Not really topical here, try comp.unix.programmer

I think it's a lot more topical here than
comp.unix.programmer Essentially he's
asking about compiling methodology not
how to write a shell script and makefiles
are not Unix specific.
But: using a makefile would ensure that the target gets build afresh
whenever the source has changed (i.e is newer than the target), a shell
script would always compile, unconditionally, regardless whether it is
acctually neccessary.

And this is a topical reply.
 
D

Dan

pereges said:
Do you see anything wrong about this method ? For eg. I write a shell
script a.sh containing :

cc -o test file1.c file2.c file3.c

and then execute the shell script ( sh a.sh) to compile and create the
executable. What is the difference between this method and writing a
make file ?

Nothing. As programs get more complicated that would have to many files to
type out, and make file you can write them to have the ability to only
recompile the files that have actually changed since last time, so large
projects compile much more quickly.
 
S

Spiros Bousbouras

pereges said:




Make files save on typing and braining. Which would you rather have to
remember and type: this...

$ cc -o test file1.c file2.c file3.c

or this?

$ make

But he wouldn't type cc -o test file1.c file2.c file3.c
he would type ./myscript or something shorter.
In any case for short programmes not using a
makefile is fine. And you don't even need a shell
script, the first time you compile you type the
whole cc... stuff but from then on just !cc
 
P

pereges

Make files save on typing and braining. Which would you rather have to
remember and type: this...

$ cc -o test file1.c file2.c file3.c

or this?

$ make

It's no contest, right? Also, make only bothers to compile stuff that needs
compiling. If you haven't touched file3.c, why bother to recompile it? It
only needs to be re-linked. So if you separate compilation from linking,
you can save yourself some actual time.

hello, i think this C program for generating make files on linux was
written by you which I found by searching through archives :

---------------------------------------------------------------------------------------------------
#include <stdio.h>

void genflags(void)
{
puts("CC=gcc");
puts("CFLAGS=-W -Wall -ansi -pedantic -O2");
puts("DFLAGS=-g -pg");

}

void makeprg(int argc, char **argv)
{
int i = 0;
printf("%s: %s.o", argv[1], argv[1]);
for(i = 2; i < argc; i++)
{
printf(" %s.o", argv);
}
printf("\n\t$(CC) $(CFLAGS) $(DFLAGS) -o %s %s.o", argv[1],
argv[1]);
for(i = 2; i < argc; i++)
{
printf(" %s.o", argv);
}
putchar('\n');

}

void makeobjs(int argc, char **argv)
{
int i = 0;
for(i = 1; i < argc; i++)
{
printf("%s.o: %s.c\n", argv, argv);
printf("\t$(CC) $(CFLAGS) $(DFLAGS) -c -o %s.o %s.c\n", argv,
argv);
}
putchar('\n');

}

void makeclean(int argc, char **argv)
{
int i = 0;
printf("clean:\n");
for(i = 1; i < argc; i++)
{
printf("\trm %s.o\n", argv);
}
printf("\trm %s\n", argv[1]);
putchar('\n');
}

void makeinstall(int argc, char **argv)
{
printf("install:\n");
printf("\tcp %s /usr/local/bin\n", argv[1]);
putchar('\n');

}

int main(int argc, char **argv)
{
if(argc > 1)
{
genflags();
makeprg(argc, argv);
makeobjs(argc, argv);
makeclean(argc, argv);
makeinstall(argc, argv);
}
else
{
fputs("Usage: makegen progname [sourcename*]\n", stderr);
}
return 0;

}
 
P

pereges

But he wouldn't type cc -o test file1.c file2.c file3.c
he would type ./myscript or something shorter.
In any case for short programmes not using a
makefile is fine. And you don't even need a shell
script, the first time you compile you type the
whole cc... stuff but from then on just !cc

Yes, but if you want to add new modules to your project then the shell
script has to be changed.
 
E

Eligiusz Narutowicz

Dan said:
Nothing. As programs get more complicated that would have to many files to
type out, and make file you can write them to have the ability to only
recompile the files that have actually changed since last time, so large
projects compile much more quickly.

This is totally wrong. There is a lot of difference. For a start this
will always compile all the files. Make only compiles the ones which
have changed.
 
A

Antoninus Twink

hello, i think this C program for generating make files on linux was
written by you which I found by searching through archives :

To be honest, this program is a bit of a joke. Several major problems
were pointed out before, and none of them seem to be fixed in the code
below. To give just one example:
void makeinstall(int argc, char **argv)
{
printf("install:\n");
printf("\tcp %s /usr/local/bin\n", argv[1]);
putchar('\n');
}

There should be a variable (usually called PREFIX) that lets you choose
to install somewhere other than a privileged system-wide directory.
Wherever it gets installed, it should be chmod'd to set appropriate
permissions. The right tool for installing files is (duh!) install, not
cp.

I know it's overwhelming when you first start out, but the GNU autotools
really are the gold standard in automating compilation, especially for
cross-platform deployment. It's overkill for a small project, of course,
but time spent learning about autoconf and automake is an investment for
the future.

Writing correct makefiles is far from being a trivial task, so why not
take advantage of the fact that someone else has already done it to a
highly professional standard? Above all, relying on Heathfield to
reinvent the wheel badly is just a mistake.
 
J

Joachim Schmitz

pereges said:
Make files save on typing and braining. Which would you rather have to
remember and type: this...

$ cc -o test file1.c file2.c file3.c

or this?

$ make

It's no contest, right? Also, make only bothers to compile stuff that
needs
compiling. If you haven't touched file3.c, why bother to recompile it? It
only needs to be re-linked. So if you separate compilation from linking,
you can save yourself some actual time.

hello, i think this C program for generating make files on linux was
written by you which I found by searching through archives :

---------------------------------------------------------------------------------------------------
#include <stdio.h>

void genflags(void)
{
puts("CC=gcc");
puts("CFLAGS=-W -Wall -ansi -pedantic -O2");
puts("DFLAGS=-g -pg");

}

void makeprg(int argc, char **argv)
{
int i = 0;
printf("%s: %s.o", argv[1], argv[1]);
for(i = 2; i < argc; i++)
{
printf(" %s.o", argv);
}
printf("\n\t$(CC) $(CFLAGS) $(DFLAGS) -o %s %s.o", argv[1],
argv[1]);
for(i = 2; i < argc; i++)
{
printf(" %s.o", argv);
}
putchar('\n');

}

void makeobjs(int argc, char **argv)
{
int i = 0;
for(i = 1; i < argc; i++)
{
printf("%s.o: %s.c\n", argv, argv);
printf("\t$(CC) $(CFLAGS) $(DFLAGS) -c -o %s.o %s.c\n", argv,
argv);
}
putchar('\n');

}

void makeclean(int argc, char **argv)
{
int i = 0;
printf("clean:\n");
for(i = 1; i < argc; i++)
{
printf("\trm %s.o\n", argv);
}
printf("\trm %s\n", argv[1]);
putchar('\n');
}

void makeinstall(int argc, char **argv)
{
printf("install:\n");
printf("\tcp %s /usr/local/bin\n", argv[1]);
putchar('\n');

}

int main(int argc, char **argv)
{
if(argc > 1)
{
genflags();
makeprg(argc, argv);
makeobjs(argc, argv);
makeclean(argc, argv);
makeinstall(argc, argv);
}
else
{
fputs("Usage: makegen progname [sourcename*]\n", stderr);
}
return 0;

}

----------------------------------------------------------------------------------------------------


I would like to use this for my project. Can you please tell me what
is the purpose behind the functions makeclean and makeinstall ?

Just for the fun of it I've writen that program as a shell script:
$ cat makegen.sh
#!/bin/sh

if [ $# -gt 1 ]
then
# genflags
cat <<-!
CC=gcc
CFLAGS= -W -WALL -ansi -pedantic -O2
DFLAGS=-g -pg

!

# makeprg
printf '%s:' $1
for arg in $@; do
printf ' %s.o' $arg
done
printf '\n\n'

# makeobjs
for arg in $@; do
printf '%s.o: %s.c\n' $arg $arg
printf '\t$(CC) $(CFLAGS) $(DFLAGS) -c -o %s.o %s.c\n' $arg
$arg
done
printf '\n'

# makeclean
printf 'clean:\n\trm -f %s' $arg
for arg in $@; do
printf ' %s.o' $arg
done
printf '\n\n'

# makeinstall
printf 'install:\n\tcp %s /usr/local/bin\n\n' $arg
else
echo "Usage: makegen.sh progname [sourcename*]" >&2
fi
return 0


Has the advantage that to change it doesn't requite a recompile...
downside: you need a shell with builtin echo), the printf, rm and cp
commands and most importantly: it is off topic here :cool:

Bye, Jojo
 
J

Joachim Schmitz

Antoninus said:
To be honest, this program is a bit of a joke. Several major problems
RH already said that is rather primitive
were pointed out before, and none of them seem to be fixed in the code
below. To give just one example:
void makeinstall(int argc, char **argv)
{
printf("install:\n");
printf("\tcp %s /usr/local/bin\n", argv[1]);
putchar('\n');
}

There should be a variable (usually called PREFIX) that lets you
choose to install somewhere other than a privileged system-wide
directory. Wherever it gets installed, it should be chmod'd to set
appropriate permissions. The right tool for installing files is
(duh!) install, not cp.
Nope. No such command in POSIX, so mit mai not be available.
The PREFIX and chmod stuff could easily be added though
I know it's overwhelming when you first start out, but the GNU
autotools really are the gold standard in automating compilation,
especially for cross-platform deployment. It's overkill for a small
project, of course, but time spent learning about autoconf and
automake is an investment for the future.

Writing correct makefiles is far from being a trivial task, so why not
take advantage of the fact that someone else has already done it to a
highly professional standard? Above all, relying on Heathfield to
reinvent the wheel badly is just a mistake.
More than a decade ago we had to the same thing (defelop a makefile
generator) as there were enough members in the team who coudn't be bothered
to learn how to write makefiles. Not to speak of configuring the much more
complex automake...

Bye, Jojo
 
P

pereges

More than a decade ago we had to the same thing (defelop a makefile
generator) as there were enough members in the team who coudn't be bothered
to learn how to write makefiles. Not to speak of configuring the much more
complex automake...

Anyway, why is it such a big issue for most people to write a simple
makefile ? I have been reading a tutorial for the last hour and it
does not seem that hard to write simple makefiles.

eg. if there are files main.c, file1.c, file2.c

main.c includes file1.h and file2.h. file1.c includes file1.h and
file2.c includes file2.h

One can write a makefile for such a program:

# top-level rule to compile the whole program.
all: prog

# program is made of several source files.
prog: main.o file1.o file2.o
gcc main.o file1.o file2.o -o prog

# rule for file "main.o".
main.o: main.c file1.h file2.h
gcc -g -Wall -c main.c

# rule for file "file1.o".
file1.o: file1.c file1.h
gcc -g -Wall -c file1.c

# rule for file "file2.o".
file2.o: file2.c file2.h
gcc -g -Wall -c file2.c

# rule for cleaning files generated during compilations.
clean:
/bin/rm -f prog main.o file1.o file2.o



Howver, the problem that I see with this approach that one has to keep
track of all the dependencies. It will get cumbersome with huge
projects but I believe there is a way out.
 
J

Joachim Schmitz

pereges said:
Anyway, why is it such a big issue for most people to write a simple
makefile ? I have been reading a tutorial for the last hour and it
does not seem that hard to write simple makefiles.
It isn't too difficult, indeed.

Howver, the problem that I see with this approach that one has to keep
track of all the dependencies. It will get cumbersome with huge
projects but I believe there is a way out.
It is indeed not so easy to implement makefiles for a large existing code
base.

gcc -M (or -MM) would generate the list of dependencies for you. Actually in
our program we used that for the makefile generation.

Bye, Jojo
 
B

Bart

Do you see anything wrong about this method ? For eg. I write a shell
script a.sh containing :

cc -o test file1.c file2.c file3.c

and then execute the shell script ( sh a.sh) to compile and create the
executable. What is the difference between this method and writing a
make file ?

I find it fairly impossible to use either modern IDEs at one end of
the scale and makefiles at the other.

I use a simple utility, which I suppose could called be called a mini
IDE (to glorify it a little), which is given a project file like the
following (as set up for your program in the other thread):

module test.c
module bbox.c
module common.c
module radar.c
module raydetect.c
module raytrace.c
module raytriangle.c
module reader.c
module reflection.c

file bbox.h
file common.h
file radar.h
file raydetect.h
file raytrace.h
file raytriangle.h
file reader.h
file reflection.h

The utility shows a list of these files/modules and uses cursor keys
to highlight one or the other. Then, you have this extensive list of
commands:

Enter Edit (can use any editor)
C Compile
L Link
R Run
CA Compile all

Plus a few combinations of the above (this is really cutting edge...).

Point: this sort of thing really can be kept fairly simple. Of course
you need to write such an utility first.

If I didn't have this and had to use shell commands only, I'd probably
still end up with something similar by building a set of short,
dedicated .bat files (or whatever they might be called on your system)
that minimises typing.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top