Makefile only actually applied changes in main.cpp while all compiled - makefile

The title might be confusing, but that's what happened...
Here's my Makefile.
all:mystdio libmystdio.a main.o myscanf.o myprintf.o
mystdio: main.o libmystdio.a
clang++ -o mystdio main.o -L. -lmystdio -Wall -g -std=c++17
libmystdio.a: myscanf.o myprintf.o
ar cr libmystdio.a myprintf.o myscanf.o
main.o: main.cpp mystdio.hpp
clang++ -c main.cpp -Wall -g -std=c++17
myscanf.o: myscanf.cpp mystdio.hpp utilities.hpp
clang++ -c myscanf.cpp -Wall -g -std=c++17
myprintf.o: myprintf.cpp mystdio.hpp utilities.hpp
clang++ -c myprintf.cpp -Wall -g -std=c++17
clean:
rm -rf mystdio *.o *.a *.a
When I made changes in myscanf.cpp or myprintf.cpp and then make file, the output showed that it had been compiled and mystdio is updated. But actually nothing happened.
For example, let's assume I add printf(":)\n"); at the beginning of a function in myscanf.cpp. Then I call the function in main.cpp. After making file, output in the terminal tells me that myscanf.o and related files were recompiled. But when the program runs, no :) is outputed.
However, when I add printf(":)\n"); in the main function and make file, it was outputed. This did confuse me. I wonder how can I solve it.
command used:
make && ./mystdio
When I changed something in myprintf.cpp and make again, here's output from the terminal.
clang++ -c myprintf.cpp -Wall -g -std=c++17
ar cr libmystdio.a myprintf.o myscanf.o
clang++ -o mystdio main.o -L. -lmystdio -Wall -g -std=c++17
By the way, if I use make clean before make && ./mystdio, it'll work correctly, but of course that's not what "make" is designed for...
Thanks for your help in advance!

Related

Make refuses to expand my variables in the g++ compilation line

Here is my simple Makefile. I am trying to set the C macro "GIT_COMMIT" in my Makefile and pass it to the C program.
all: control
control: control.cpp serial_port.cpp
GIT_COMMIT=5
g++ -g -DGIT_COMMIT=$(GIT_COMMIT) -Wall $^ -o control -lpthread
Unfortunately, when I run make, I see this and make is completely ignoring my GIT_COMMIT variable. What am I doing wrong? Thanks.
GIT_COMMIT=5
g++ -g -DGIT_COMMIT= -Wall control.cpp serial_port.cpp -o control -lpthread
placing the setting of GIT_COMMIT as an action inside the 'control' rule will, as you discovered, not work to produce a macro. suggest:
all: control
GIT_COMMIT := 5
control: control.cpp serial_port.cpp
g++ -g -DGIT_COMMIT=$(GIT_COMMIT) -Wall $^ -o control -lpthread

relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC

So I ve been trying to recompile with -fPIC but it seems I am getting the same error, am I doing it right or am I missing something else?
all: pr1 pr2
pr1:
g++ -std=c++11 -fPIC -c $(wildcard pr1.cpp)
g++ -std=c++11 -o $(PROGRAM) pr1.o $(LIBRARY) $(LINKER_FLAGS)
rm -f pr1.o
pr2:
g++ -std=c++11 -fPIC -c $(wildcard pr2.cpp)
g++ -std=c++11 -o $(PROGRAM1) pr2.o $(LIBRARY) $(LINKER_FLAGS)
rm -f pr2.o
The problem seems to occur at the second program (pr2), possibly when I am trying to reuse LIBRARY(.a file)?
apparently I was not removing the .a library that was produced . make clean first

Why does make delete my temporary files?

I have a simple Makefile,
.PHONY: clean
PROGRAMS=$(patsubst main%.cpp,example%,$(wildcard main*.cpp))
all: ${PROGRAMS}
GCCVERSION=$(shell gcc -dumpversion)
GLCFLAGS=$(shell pkg-config --cflags gl)
CPPFLAGS=-Wall -O2 ${GLCFLAGS}
ifeq "${GCCVERSION}" "4.5.2"
CXXFLAGS=-std=c++0x
else
CXXFLAGS=-std=c++11
endif
GLLIBS=$(shell pkg-config --libs gl)
LIBS=${GLLIBS} -lglut
example%: main%.o shaders.o fileutils.o
${CXX} $^ ${LIBS} -o $#
clean:
rm -f *.o ${PROGRAMS}
But when I executed it, it delete the *.o files as last command. I don't know why:
$ make
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o main01.o main01.cpp
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o shaders.o shaders.cpp
g++ -std=c++11 -Wall -O2 -I/usr/include/libdrm -c -o fileutils.o fileutils.cpp
g++ main01.o shaders.o fileutils.o -lGL -lglut -o example01
rm main01.o fileutils.o shaders.o
Is there anything wrong with my Makefile?
Intermediate files are deleted by design: see Chained Rules in GNU make manual.
Use .SECONDARY or .PRECIOUS targets to keep your precioussss temp files.
Just to clarify the previous response, you need to add a special rule like
.PRECIOUS: myfile.o

How to get g++ to ignore warnings from included projects

I'm making a new project that is dependent on two other projects (written by others). While I'm developing my code I would like to use g++ options such as -Wall -pedantic -Werror but when I use these options I get a flood of warnings by including files from the other two projects.
Is there any way I can ignore the warnings from those two projects but still see the warnings from my own project?
If you're compiling their source directly via a makefile, you can make optional CPPFLAGSwhich you can use for conditional compilation parameters. For example:
CPPFLAGS=-Wall -pedantic -Werror for your project and CPPFLAGS=-g for their project files (or something).
Take the following sample makefile. Assume you wrote factorial.cpp and hello.cpp and they wrote main.cpp:
CPPFLAGS+=-Wall -pedantic -Werror
all: hello
hello: main.o factorial.o hello.o
g++ main.o factorial.o hello.o -o hello
main.o: main.cpp
g++ -c main.cpp
factorial.o: factorial.cpp
g++ -c $(CPPFLAGS) factorial.cpp
hello.o: hello.cpp
g++ -c $(CPPFLAGS) hello.cpp
clean:
rm -rf *o hello
Try something like that and get back to me.

File format not recognized; treating as linker script using GCC

I am pretty new to Makefiles and i am trying to build an executable from 3 files, file1.c, file2.c, and file1.h into an executable called exFile. Here's what I got:
all: exFile
exFile: file1.o file2.o
gcc -Wall -g -m32 repeat.o show.o -o repeat
file1.o: file1.c file1.h
gcc -Wall -g -m32 -S file1.c -o file1.o
file2.o: file2.c
gcc -Wall -g -m32 -S file2.c -o file2.o
I've searched the web for makefiles in this format, but i came up empty handed so i was wondering if someone can help. When it tries to compile i get:
usr/bin/ld:file1.o:1: file format not recognized; treating as linker script
I've compiled programs using assembly files but I'm not to sure what to do with c files or the file1.h file. file1.c includes file1.h so i have to link them (I think?). Any suggestions or links to a reference would be appreciated
You have two problems with your gcc command-line. First, you're specifying the -S flag, which causes gcc to emit assembly code, rather than object code. Second, you're missing the -c flag, which tells gcc to compile the file to an object file, but not link it. If you just remove -S and change nothing else, you'll end up with an executable program named file1.o and another named file2.o, rather than two object files.
Besides those errors, you could simplify your makefile by the use of pattern rules. I suggest you try the following instead:
all: exFile
exFile: file1.o file2.o
gcc -Wall -g -m32 $^ -o $#
%.o: %.c
gcc -Wall -g -m32 -c $< -o $#
file1.o: file1.h
Or, as EmployedRussian points out, you can go with something even more minimal that leverages more of the built-in features of GNU make:
CC=gcc
CFLAGS=-Wall -g -m32
all: exFile
exFile: file1.o file2.o
$(LINK.c) $^ -o $#
file1.o: file1.h
The -S switch to gcc tells it to output assembler so this:
gcc -Wall -g -m32 -S file1.c -o file1.o
Is putting assembler into file1.o but you want, presumably, to compile file1.c into object code:
gcc -Wall -g -m32 file1.c -o file1.o
When the linker gets your file1.o it is confused because file1.o is assembler when the linker is expecting object code, hence your error.
So get rid of the -S switches for file1.o and file2.o.

Resources