How can I specify the objects directory makefile? - c

How can I specify the directory of the .o files in this GCC command?
gcc -c -Wall -Wextra -Werror src/*.c

Use -o to specify the target. You can choose any directory you like.

Related

Compilation error on linux server (C project)

I need some help.
I worked on a C project locally and it ran perfect with no issues at all.
Then I moved my whole project files to a linux server (using Bitwise) and ran it using the following command:
gcc -g -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG main.c map.c map.h utilities.c
utilities.h election.c election.h extended_map.c extended_map.h test_utilities.h -o outmap
and again everything worked as expected.
Now, I want to replace my version of test_utilities.h with the version saved on that server, so I opened main.c (which is the only file to include test_utilities.h and replaced:
#include "test_utilities.h"
with
#include "~mtm/public/1920b/ex1/test_utilities.h"
But the terminal shows me the following error:
gcc: error: test_utilities.h: No such file or directory
-bash-4.2$
As suggested I changed it to
gcc -g -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG main.c map.c map.h utilities.c utilities.h election.c election.h extended_map.c extended_map.h test_utilities.h -o outmap -I ~mtm/public/1920b/ex1/
But still I get the following:
gcc: error: test_utilities.h: No such file or directory
update2: (I was requested to remove .h files so now I got)
gcc -g -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG main.c map.c utilities.c election.c extended_map.c -o outmap
Writing ~mtm to refer to the home directory of user mtm is a shortcut that your shell understands. It isn't something that the C preprocessor understands. So you'll have to spell it out as /home/mtm (or wherever mtm's home directory is located) instead of ~mtm.
That said, a better way would be to just leave it as "test_utilities.h" and instead adjust the include path of the compiler (specified via -I when invoking the compiler) to include ~mtm/public/1920b/ex1/.
You also shouldn't specfiy test_utilities.h as an argument to the compiler. In fact none of the header files should be passed as arguments to the compiler.

Makefile: how to specify library name at the end of command using patsubst

I am new to Makefile, C and Linux. I am using gcc & ubuntu. I encountered a problem while trying to compile the code with a link to a library.
Here is my problem. I have:
a_tests.c & b_tests.c files in "tests" folder
lib.a file in "build" folder
Here is the codes in Makefile related to the problem:
CFLAGS=-g -O2 -Wall -Wextra -Isrc -DNDEBUG $(OPTFLAGS)
TARGET=build/lib.a
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
When the tests files are compiled, "undefined reference to 'XXXfunction'"errors will be prompted. Because what executed behind is
gcc -g -O2 -Wall -Wextra -Isrc -DNDEBUG build/lib.a tests/a_tests.c -o test/a_tests
gcc -g -O2 -Wall -Wextra -Isrc -DNDEBUG build/lib.a tests/b_tests.c -o test/b_tests
But "build/lib.a" should be placed after the output file name to solve it (If I manually type in the below commands, the codes would be successfully compiled), ie:
gcc -g -O2 -Wall -Wextra -Isrc -DNDEBUG tests/a_tests.c -o test/a_tests build/lib.a
gcc -g -O2 -Wall -Wextra -Isrc -DNDEBUG tests/b_tests.c -o test/b_tests build/lib.a
But I don't know how to change in the Makefile, I tried -l -L options, they didn't work. It would warn that "cannot find the .a file". Any help would be appreciated. Thank you so much in advance!
Define the library as a dependency, because it is one. It will be appended at the end of the other dependencies, here: the source.
CFLAGS=-g -O2 -Wall -Wextra -Isrc -DNDEBUG $(OPTFLAGS)
TARGET=build/lib.a
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(TEST_SRC:%.c=%)
tests: $(TESTS)
$(TESTS): $(TARGET)
The library does not need to be after the output file, but after the depending input file.
The makefile is further simplified:
Replaced the patsubst with a simpler expression.
Moved the target tests up, so it is found as the first and therefore default target.
Good luck!

FLAG=-DNDEBUG is not disabling assert() in 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.

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