FLAG=-DNDEBUG is not disabling assert() in C - c

I have a bunch of assert() functions I used throughout my C files and from reading I have done I should be able to disable the assertions by passing in a command line parameter like so:
make
Doing this does not disable the assertions. However, adding into the code, #define NDEBUG does disable the assertions. I want to disable them from the command line though. Is there a reason why this flag is not working correctly?
I am on a Windows machine.
Here is the makefile:
OPTIONS = -B CFLAGS=-DNDEBUG -ansi -pedantic -Wall -Werror
a.out: myProgram.o StudentImplementation.o ListImplementation.o
gcc $(OPTIONS) myProgram.o StudentImplementation.o ListImplementation.o
myProgram.o: myProgram.c StudentInterface.h StudentType.h ListInterface.h ListType.h
gcc $(OPTIONS) -c myProgram.c
StudentImplementation.o: StudentImplementation.c StudentInterface.h StudentType.h
gcc $(OPTIONS) -c StudentImplementation.c
ListImplementation.o: ListImplementation.c ListInterface.h ListType.h StudentInterface.h StudentType.h
gcc $(OPTIONS) -c ListImplementation.c
clean:
rm *.o a.out

If you have a normal makefile or no makefile, then the command you want is
make -B CFLAGS=-DNDEBUG
There is no FLAG variable in the standard make recipes; each component has its own variable, so CFLAGS is for C, CXXFLAGS is for C++, LDFLAGS is for the linker, and so on.
With the Makefile you provide in the question, you cannot change flags on the make command line. You could use
OPTIONS = -DNDEBUG -ansi -pedantic -Wall -Werror
but that means editing your Makefile every time you want to change the debug setting.

You simply need
OPTIONS = -DNDEBUG -ansi -pedantic...
However a simpler Makefile would look like this
CFLAGS = -DNDEBUG -ansi -pedantic -Wall -Werror -I.
a.out: myProgram.o StudentImplementation.o ListImplementation.o
clean:
rm *.o a.out

According to my Unix makefile experience, the default flag should be CFLAGS, unless of course FLAG is explicitly used in your makefile. However, defining CFLAGS on the command line is not recommended since it is overriding a make variable.
Are there any -DNDEBUG in the compiler call invocations? If not, perhaps the problem lies in the Makefile itself, and you will have to provide its relevant data.

Related

How to create command in bash to compile multiple C program with multiple flags

So my file structure is basically this -
I have a .zshrc file since I'm on OS X
I have a .my_custom_commands.sh file which contains the shortcuts I want
In my .zshrc I source the commands file
Currently, I'm looking for a solution to compile multiple files with flags using the "gcc" command
For example, if I want to compile a.c and b.c
gcc -Wall -Werror -ansi -pedantic -o output.c a.c b.c
However, I don't want to type this out every time, so I was thinking there would be a way to create a custom command say 'gccf' (gcc flags). The thing is that I don't know zsh programming language so I'm just wondering if there is a way to pass multiple args into the function I created in the commands file.
I have something like this right now
function gccf() {
gcc -Wall -Werror -ansi -pedantic -o output.c $1 $2
}
I understand that the args you pass into the command line are represented by $1, $2..., but is there anyway to check how many args have been passed? Because if $2 isn't passed then this won't work I think.
Set CFLAGS as you want and just use the default rules for make. You don't even need a makefile:
$ rm -f Makefile
$ ls a.c
a.c
$ make a
cc a.c -o a
$ rm -f a.o a
$ export CFLAGS=-pedantic
$ make a
cc -pedantic a.c -o a
If you have multiple source files, you'll need a (trivial) makefile:
$ rm -f a *.o output Makefile
$ unset CFLAGS
$ make a
cc a.c -o a
$ export CFLAGS='-Wall -Werror -ansi -pedantic'
$ rm a; make a
cc -Wall -Werror -ansi -pedantic a.c -o a
$ printf 'output: a.o b.o\n\t$(CC) $(LDFLAGS) $^ -o $# $(LDLIBS)\n' > Makefile
$ make output
cc -Wall -Werror -ansi -pedantic -c -o a.o a.c
cc -Wall -Werror -ansi -pedantic -c -o b.o b.c
cc a.o b.o -o output
$ rm -rf *.o output
$ export CC=gcc LDLIBS=-lm
$ make output
gcc -Wall -Werror -ansi -pedantic -c -o a.o a.c
gcc -Wall -Werror -ansi -pedantic -c -o b.o b.c
gcc a.o b.o -o output -lm
In other words, don't try to reinvent the wheel. Your use case has been encountered by many people, and there are long standing conventions and tools in place to enable the work flow.
Note that you may want to include LOADLIBES along with LDLIBS, but the former name should (probably?) no longer be used.
In Bourne-heritage shells (e.g. sh, zsh, bash, ksh), to specify all arguments passed to a program or function, use "$#" (including the double quotes!), which expands to any number of args passed, including none.
But if you follow the Unix philosophy of using the one tool that does just one thing, you want to look at make as suggested in comments and other answers.
PS: you also want -o output, not -o output.c, since your program is not a C source file, but an executable.

How enable c99 mode in gcc with terminal

I want to activate c99 mode in gcc compiler to i read in other post in this forum that -std should be equal to -std=c99 but i don't know how to set it to this value using command line so please help.
Compile using:
gcc -std=c99 -o outputfile sourcefile.c
gcc --help lists some options, for a full list of options refer to the manuals. The different options for C dialect can be found the section "Options Controlling C Dialect" in any gcc version's manual (e.g., here).
As you are using make you can set the command line options for gcc using CFLAGS:
# sample makefile
CC = gcc
CFLAGS = -Wall -std=c99
OUTFILE = outputfile
OBJS = source.o
SRCS = source.c
$(OUTFILE): $(OBJS)
$(CC) $(CFLAGS) -o $(OUTFILE) $(OBJS)
$(OBJS): $(SRCS)
$(CC) $(CFLAGS) -c $(SRCS)
Addendum (added late 2016): C99 is getting kind of old by now, people looking at this answer might want to explore C11 instead.
You may try to use the -std=c99 flag.
Try to complile like this:
gcc -Wall -std=c99 -g myProgram.c
Also note that -g is for debugging option(Thanks Alter Mann for pointing that).
Based on the comments under another answer, perhaps you are using the implicit make rules and don't have a Makefile. If this, then you are just runing make tst to generate tst binary from tst.c. In that case you can specify the flags by setting the environment variable CFLAGS. You can set it for the current shell, or add it to your ~/.bashrc to have it always, with this:
export CFLAGS='-Wall -Wextra -std=c99'
Or specifying it just for the single command:
CFLAGS='-Wall -Wextra -std=c99' make tst
(Note: I added warning flags too, you should really use them, they will detect a lot of potential bugs or just bad code you should write differently.)

Using Make for compiling C

I am trying to learn make to make my compiling easier as I learn C.
I am attempting to do:
gcc -Wall -g 3.c -o 3 -lm
using
CC = gcc
CFLAGS = -Wall -g
clean:
rm -f 3
but I don't know how and where to put -lm in the makefile. I've looked for tutorials online but they haven't specifically addressed the "-lm" option, or if they do it is without little explanation and doesn't work in my situation.
You need a "target" in which to execute the gcc command. Like:
CC = gcc
CFLAGS = -Wall -g
all:
gcc -Wall -g 3.c -o 3 -lm
clean:
rm -f 3
Then you can just replace parts of the "all" command, with your macros; CFLAGS, for example would probably have the "-lm".
It might help if you ran "make -n", that will tell you what make would do if it were to run.
Often you'll see library specific flags in a LIBS variable, e.g.:
CC = gcc
CFLAGS = -Wall -g -I/some/include/directory
LIBS = -lm -L/some/library/directory
all:
$(CC) $(CFLAGS) $(LIBS) 3.c -o 3
The variable you are looking for is called LDLFAGS. From §10.3 of the GNU Make manual:
LDFLAGS
Extra flags to give to compilers when they are supposed to invoke the linker, ‘ld’.
So, simply do:
LDFLAGS += -lm
Hope it helps.
An extremely good tutorial: Make Tutorial: How-To Write A Makefile
and here is a good generic makefile I wrote:
http://pastebin.com/PCk0gNtE
The part that would most interest you would be this section:
# C Preprocessor Flags
CPPFLAGS +=
# compiler flags
CFLAGS += -ansi -Wall -Wextra -pedantic-errors
# libraries to link to ( m == math )
program_LIBRARIES := m
# LDFLAGS is the variable to hold linker flags
LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library))
GNU make defines a lot of default rules. For C compilation and linking, those rules are:
n.o is made automatically from n.c with a recipe of the form ‘$(CC) $(CPPFLAGS) $(CFLAGS) -c’.
n is made automatically from n.o by running the linker (usually called ld) via the C compiler. The precise recipe used is ‘$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)’.
So the way to add "-lm" option to the linker is by defining:
LDLIBS = -lm
Then when you run make with your Makefile, you following commands will be run:
gcc -Wall -g -c 3.c
gcc 3.o -o 3 -lm
(note that make will compile your C program in 2 steps, first creating the object file 3.o then linking the object file into the executable 3)
(see http://www.gnu.org/software/make/manual/ for the GNU make manual)

make is automatically attempting to link even when I pass -c in my makefile

I'm new to makefiles, so I apologize in advance if this is a silly question. Also I removed most variables from my makefile because they weren't working properly (gnu make tells me that $(myvar) should be completely replaces by the value of myvar, however the output of make was showing me that this was not happening), so I apologize for the ugliness and the more than 80 character lines.
acolibobj = acoLibInit acoGlobalDefs
acolibinterface: $(acolibobj).o
acoLibInit.o:
gcc -fPIC -g -c -Wall -I/usr/include/dc1394 -o acoLibinit.o acoCommands/acoLibInterface/acoLibInit.c
acoGlobalDefs.o:
gcc -fPIC -g -c -Wall -I/usr/include/dc1394 -o acoGlobalDefs.o acoCommands/acoLibInterface/acoGlobalDefs.c
When I run this makefile I get:
gcc -fPIC -g -c -Wall -I/usr/include/dc1394 -o acoLibinit.o acoCommands/acoLibInterface/acoLibInit.c
cc acoLibInit.o -o acoLibInit
gcc: acoLibInit.o: No such file or directory
gcc: no input files
make: *** [acoLibInit] Error 1
So far as I can tell, what's happening is that make is trying to compile AND link, even though I explicitly added the -c flag. When I run "gcc -fPIC -g -c..." myself (from bash), I do not get any problems at all. Why does make go on to try "cc acoLibInit.o -o acolibInit"?
make is trying to build acoLibInit. It probably has built-in rule that specifies "whatever" can be produced by linking "whatever.o", which is why you get that cc line.
This line:
acolibinterface: $(acolibobj).o
expands to:
acolibinterface: acoLibInit acoGlobalDefs.o
(note the absence of .o on the first dependency). This is why it's trying to link acoLibInit.
Try this:
acolibinterface: $(addsuffix .o,$(acolibobj))
if you want only the .o files as dependencies for that target.
$(acolibobj).o expands to acoLibInit acoGlobalDefs.o. Thus, you're really saying:
acolibinterface: acoLibInit acoGlobalDefs.o
Simply define acolibobj = acoLibInit.o acoGlobalDefs.o and use acolibinterface: $(acolibobj).

how to create a makefile with several sub-directories

I have one directory and underneath it 4 subdirectories like so:
myDir:
myDir/Part1
myDir/Part2
myDir/Part3
myDir/shared
I want to make an executable that takes files from shared, links it to files in Part2 and puts the executable in myDir.
This is what I tried (only the lines in the makefile that are relevant):
Shared/helper.o:
gcc -ansi -pedantic-errors -c -Wall -Werror -g -o Shared/helper.o Shared/helper.c
and above it in the makefile:
Part2/part2code.o: ../Shared/helper.o
gcc -ansi -pedantic-errors -c -Wall -Werror -g -o Part2/part2code.o Part2/part2code.c
and above it in the makefile:
part2code: Part2/part2code.o ../Shared/helper.o
gcc -ansi -pedantic-errors -Wall -Werror -g -lm -o part2code Part2/part2code.o ../Shared/helper.o
(I also tried without the ../ before Shared)
I get this error:
No such file or directory.
help?
Thanks!
In this context, paths in filenames are all relative to where the makefile is. So e.g. Part2/part2code.o: ../Shared/helper.o is incorrect; it should simply be Part2/part2code.o: Shared/helper.o (and so on). Note also that you've written Shared in your makefile, but you've listed your directory as shared...
Although actually, that's still wrong. Rules such as a: b express that b is a prerequisite of a; i.e. that you cannot make a until you've made b. That is not the case for your object files; they don't depend on each other. Usually, an object file depends purely on its constituent source files (*.c and *.h). So, for example, your rule for part2code.o might be something like:
Part2/part2code.o: Part2/part2code.c
gcc -ansi -pedantic-errors -c -Wall -Werror -g -o $# $^
(Note the use of the special variables $# and $^, which substitute in for the target and the prerequisites, respectively.)

Resources