user6138916
user6138916

Reputation:

Custom make command for learning

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

Answers (4)

user6138916
user6138916

Reputation:

mk() {
    output="${1%.c}"
    echo "gcc -ggdb -std=c99 -Wall -Werror ${@} -o $output";
    gcc -ggdb -std=c99 -Wall -Werror ${@} -o $output;
}

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

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

Useless
Useless

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

Honza Remeš
Honza Remeš

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

Related Questions