Reputation:
I want to have a make command like this but to which I can pass many arguments and the name of the resulting file is the name of the first one.
It has to accept the name with .c and remove the .c from the source file name for the executable name.
# My custom make command
mk() {
echo "gcc -ggdb -std=c99 -Wall -Werror ${1}.c -o $1";
gcc -ggdb -std=c99 -Wall -Werror ${1}.c -o $1 ;
}
Something like this maybe?
mk() {
echo "gcc -ggdb -std=c99 -Wall -Werror ${@} -o $1";
output=$1
set -- "${@/%/.c}"
gcc -ggdb -std=c99 -Wall -Werror ${@} -o $output;
}
Upvotes: 0
Views: 83
Reputation:
mk() {
output="${1%.c}"
echo "gcc -ggdb -std=c99 -Wall -Werror ${@} -o $output";
gcc -ggdb -std=c99 -Wall -Werror ${@} -o $output;
}
Upvotes: 0
Reputation: 754860
Use a makefile
— probably one like Honza Remeš suggests in their answer, or a somewhat more complex one like this, which is closely based on what I use when working on Stack Overflow questions. It allows me to configure which compilation options are used with great granularity. This is probably overkill for you at the moment — Honza's version is a good starting point — but you may eventually get fussy enough for this to be of benefit.
CC = gcc
DFLAGS = #-DHAVE_CONFIG_H
GFLAGS = -g
IFLAG1 = #-I${INCDIR}
IFLAG2 = #-I${HOME}/inc
IFLAGS = #${IFLAG1} ${IFLAG2}
OFLAGS = -O3
SFLAGS = -std=c11 # -pedantic
UFLAGS = # Set on command line
WFLAG1 = -Wall
WFLAG2 = -Wextra
WFLAG3 = -Werror
WFLAG4 = -Wmissing-prototypes
WFLAG5 = -Wstrict-prototypes
WFLAG6 = #-Wold-style-declaration # Strict GCC only (not clang, it would seem).
WFLAG7 = #-Wold-style-definition # Part of -Wextra in GCC 7.1.0
WFLAGS = ${WFLAG1} ${WFLAG2} ${WFLAG3} ${WFLAG4} ${WFLAG5} ${WFLAG6} ${WFLAG7}
LDFLAG1 = #-L${LIBDIR}
LDFLAG2 = #-L${HOME}/lib/64
LDFLAGS = ${LDFLAG1} ${LDFLAG2}
LDLIB1 = #-l${SOQBASE}
LDLIB2 = #-l${CS50BASE}
LDLIBS = ${LDLIB1} ${LDLIB2}
CFLAGS = ${OFLAGS} ${GFLAGS} ${DFLAGS} ${IFLAGS} ${SFLAGS} ${WFLAGS} ${TFLAGS} ${UFLAGS}
DEBRIS = core a.out *~ *.o
RM_FR = rm -fr
RM_F = rm -f
default:
@echo "You must specify a target to build"
#all:
# ...rules for what to do for 'make all'
# Provides target 'clean' to do sensible cleaning.
# Relies on user to set macro PROGRAMS (plural) for removing programs.
# OUTFILES can be set per makefile to hold output file names that should
# be cleaned. OUTDIRS can be set per makefile to hold output directory
# names that should be cleaned.
# .dSYM directories are an artefact of building single-file programs on
# .Mac OS X (or using dsymutil).
.DEFAULT:
@echo "No commands specified for building $@"
clean:
${RM_F} *.o *.a ${DEBRIS} ${OUTFILES}
${RM_F} ${PROGRAMS}
${RM_FR} *.dSYM ${OUTDIRS}
The UFLAGS
option, in particular, is one I use for 'user flags' — something that I want to add to a particular compilation. I could use:
make UFLAGS="-Wshadow -Wpointer-arith" newprog53
to add the extra warning options -Wshadow -Wpointer-arith
to the compiler command line.
You can find the full version of this makefile in three files:
makefile
etc/soq-head.mk
etc/soq-tail.mk
in my SOQ (Stack Overflow Questions) repository on GitHub.
Upvotes: 0
Reputation: 67812
To answer your specific question, bash has a way to remove suffix patterns (like .c
for example):
mk() {
SOURCE="$1"
DEST="${1%.c}"
echo "gcc -ggdb -std=c99 -Wall -Werror ${SOURCE}.c -o $DEST";
gcc -ggdb -std=c99 -Wall -Werror "${SOURCE}.c" -o "$DEST" ;
}
You should learn to use make properly anyway, but that's no reason you can't also learn bash.
Upvotes: 0
Reputation: 1183
You can write a Makefile
which will allow you to create multiple targets with a single rule.
In fact, building a <FOO>
from <FOO>.c
is something for which make
has a predefined rule, so you can create a Makefile with
CC = gcc
CFLAGS = -ggdb -std=c99 -Wall -Werror
and then run make bar
.
As long as there is a file named bar.c
, make
will build it for you.
Upvotes: 5