mingw32-make only runs the first dependency line - makefile

My Makefile:
helloworldlib.obj: helloworldlib.cpp
g++ -Wall -o helloworldlib.obj -c helloworldlib.cpp
helloworld.obj: source.cpp
g++ -Wall -o helloworld.obj -c source.cpp
helloworld.exe: source.cpp helloworld.obj
g++ -Wall -o helloworld.exe helloworld.obj helloworldlib.obj
I'm not sure what's wrong with this, when I run mingw32-make it only executes the first g++ -Wall -o helloworldlib.obj -c helloworldlib.cpp.
As far as I know this makefile is syntactically correct, mingw just doesn't seem to be able to find the other lines.

This is how make works. If no target is provided on the command line (e.g. mingw32-make helloworld.exe), by default it builds the first target defined in the file. See for instance: https://stackoverflow.com/a/2057716/2249356.
As a quick fix, you can just move the rule for helloworld.exe to the top of the file and then make will build all.
And, I think that the last rule is supposed to read
helloworld.exe: helloworld.obj helloworldlib.obj
g++ -Wall -o helloworld.exe helloworld.obj helloworldlib.obj
rather then with the source.cpp and its object code helloworld.obj as dependencies.

Related

Two stage compiling fails while single stage succeeds

I am trying to compile a simple Antlr4 project. When I do it in single g++ command, it compiles successfully. However, when I compile and link separately, it fails.
Single stage compilation (succeeds):
g++ -std=c++11 -Wall -Wextra *.cpp -L. -l antlr4-runtime -I/usr/local/include/antlr4-runtime -. -o exec
Two stage (fails: cannot link properly to antlr library and gives a lot of undefined reference errors):
main: $(OBJS)
g++ -L. -l antlr4-runtime $^ -o exec
%.o: %.cpp
g++ -std=c++11 -Wall -Wextra -I/usr/local/include/antlr4-runtime -I. -c $<
I wonder why linking fails in the latter case, while it has similar linking options to single stage compiling.

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

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!

Makefile: "No such file or directory" for target file

First, I should admit makefiles are something that I'm very inexperienced at, so I apologize if this is an error that I should have been able to solve myself, but I have spent several hours on this, including reading the various answers on this site, and have been unable to discover a solution.
With that said, I have created the following makefile to compile my code on a Linux machine; it completes the sub compilations just fine, but when it comes to making the output itself, xPlatST, it throws an error.
g++ -std=c+=11 -g -Wall -pthread -c -o xPlatST.o xPlatST.cpp
g++ -std=c+=11 -g -Wall -pthread -c -o stdafx.o stdafx.cpp
g++ -std=c+=11 -g -Wall -pthread -c xPlatST xPlatST.o stdafx.o -L../hwloc
g++ error: xPlatST: No such file or directory
make: *** [xPlatST] Error 1
I believe it seems to think that the xPlatST is one of it's compilation files and thus can't find it, but for the life of me I can't work out why.
hwloc is a third party library, and should be unrelated to this issue. The code compiles just fine when compiled from the command line directly.
My files are xPlatST.cpp, xPlatST.h, stdafx.cpp, stdafh.h
Code is as follows:
CXX = g++ -std=c++11
INCLUDES =
LIBS = -L../hwloc
CXXFLAGS = -Wall -g -pthread
OBJS = xPlatST.o stdafx.o
xPlatST: ${OBJS}
${CXX} ${CXXFLAGS} ${INCLUDES} -c $# ${OBJS} ${LIBS}
clean:
-rm xPlatST *.o
Any help would be greatly appreciated; thank you in advance.
Your assumption is correct. Your recipe is trying to use xPlatST as a source. Change the -c into a -o in your rule:
${CXX} ${CXXFLAGS} ${INCLUDES} -o $# ${OBJS} ${LIBS}
The -c flag tells the compiler to take all files, compile, and assemble them into an object file (.o). The -o flag specifies the destination file.

MinGW compilation "file not recognized: File format not recognized"

I'm trying to compile a c++ program and I am having some issues. In particular, when I use x86_64-w64-mingw32-gcc as my compiler, it complains half way through my compilation saying "tmp/src/libfastms/solver/solver.cpp.o: file not recognized: File format not recognized".
Here is my makefile (not mine, I'm trying to adapt this makefile to a cygwin environment) https://pastebin.com/vgnVYJUL
Here is the console output when I run make:
x86_64-w64-mingw32-gcc -c -o tmp/src/libfastms/solver/solver.cpp.o src/libfastms/solver/solver.cpp -Wall -O3 -m64 -Isrc/libfastms -DDISABLE_OPENMP -DDISABLE_OPENCV -DDISABLE_CUDA
x86_64-w64-mingw32-gcc -c -o tmp/src/libfastms/solver/solver_base.cpp.o src/libfastms/solver/solver_base.cpp -Wall -O3 -m64 -Isrc/libfastms -DDISABLE_OPENMP -DDISABLE_OPENCV -DDISABLE_CUDA
x86_64-w64-mingw32-gcc -c -o tmp/src/libfastms/solver/solver_host.cpp.o src/libfastms/solver/solver_host.cpp -Wall -O3 -m64 -Isrc/libfastms -DDISABLE_OPENMP -DDISABLE_OPENCV -DDISABLE_CUDA
x86_64-w64-mingw32-gcc -c -o tmp/src/libfastms/util/has_cuda.cpp.o src/libfastms/util/has_cuda.cpp -Wall -O3 -m64 -Isrc/libfastms -DDISABLE_OPENMP -DDISABLE_OPENCV -DDISABLE_CUDA
x86_64-w64-mingw32-gcc -c -o tmp/src/libfastms/util/image_mat.cpp.o src/libfastms/util/image_mat.cpp -Wall -O3 -m64 -Isrc/libfastms -DDISABLE_OPENMP -DDISABLE_OPENCV -DDISABLE_CUDA
ld -r -o tmp/src/libfastms/libfastms.o tmp/src/libfastms/solver/solver.cpp.o tmp/src/libfastms/solver/solver_base.cpp.o tmp/src/libfastms/solver/solver_host.cpp.o tmp/src/libfastms/util/has_cuda.cpp.o tmp/src/libfastms/util/image_mat.cpp.o
tmp/src/libfastms/solver/solver.cpp.o: file not recognized: File format not recognized
Makefile:167: recipe for target 'tmp/src/libfastms/libfastms.o' failed
make: *** [tmp/src/libfastms/libfastms.o] Error 1
Some other notes:
I don't have this problem when I compile with g++ (only seems to be minGW)
A common solution to this problem is to clean the directory of residual object files. This does not work.
Another common reason for this is trying to compile .h files. Obviously I am not doing this.
Thanks in advance.
You are compiling your object files with a 64-bit compiler driver, w64-mingw32-gcc,
and with -m64 you are explicitly directing it to generate 64-bit code (unnecessarily,
as that is its default). But you are linking with a 32-bit linker that does not
understand 64-bit object files.
This is happening because in your makefile you are, unusually, invoking ld
explicitly for your incremental solver linkage:
COMMAND_LINK_SOLVER=ld -r -o $# $^
rather than delegating linkage to your compiler driver in the usual way, and
a 32-bit ld from a different toolchain is being found in your PATH before
the 64-bit one belonging to your mingw-w64 toolchain.
To avoid this, invoke the linker via the compiler driver as normal, which for your
solver linkage means:
COMMAND_LINK_SOLVER=$(GXX) -Wl,-r -o $# $^
You can depend on w64-mingw32-gcc to invoke the ld that was installed with it.
There is no need to correct your main linkage as it is already done the right way.

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