File format not recognized; treating as linker script using GCC - 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.

Related

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!

Creating a makefile for CUDA programs

I want to automate the compilation of a toy library using CUDA and C++. Then I write a Makefile as follows
CC=g++
NVCC=nvcc
CXXFLAGS= -fopenmp -O3 -Wextra -std=c++11
CUDAFLAGS= -std=c++11 -c -arch=sm_20
LIBS= -lopenblas -lpthread -lcudart -lcublas
LIBDIRS=-L/usr/local/cuda-7.5/lib64
INCDIRS=-I/usr/local/cuda-7.5/include
matrix_cuda.o: marix_cuda.cu
$(NVCC) $(CUDAFLAGS) matrix_cuda.cu
all: matrix_cuda.o
$(CC) -o test matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o $(LIBDIRS) $(INCDIRS) $(LIBS) $(CXXFLAGS)
clean:
rm -rf test *.o
Typing make I get
make: *** No rule to make target `marix_cuda.cu', needed by `matrix_cuda.o'. Stop.
I never wrote a Makefile before. Where did I go wrong?
I think you have a typo in the CUDA file name
matrix_cuda.o: marix_cuda.cu
$(NVCC) $(CUDAFLAGS) matrix_cuda.cu
IMHO it should be
matrix_cuda.o: matrix_cuda.cu
$(NVCC) $(CUDAFLAGS) matrix_cuda.cu
This may take a couple of iterations.
1) First try this:
nvcc -std=c++11 -c -arch=sm_20 matrix_cuda.cu
If that works (and produces matrix_cuda.o, I presume), remove matrix_cuda.o and
2) try this makefile:
matrix_cuda.o: matrix_cuda.cu
nvcc -std=c++11 -c -arch=sm_20 matrix_cuda.cu
If that works,
3) try this:
g++ -o test matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o -L/usr/local/cuda-7.5/lib64 -I/usr/local/cuda-7.5/include -lopenblas -lpthread -lcudart -lcublas -fopenmp -O3 -Wextra -std=c++11
If that works, remove test and
4) try this makefile:
test: matrix_cuda.o
g++ -o test matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o -L/usr/local/cuda-7.5/lib64 -I/usr/local/cuda-7.5/include -lopenblas -lpthread -lcudart -lcublas -fopenmp -O3 -Wextra -std=c++11
matrix_cuda.o: matrix_cuda.cu
nvcc -std=c++11 -c -arch=sm_20 matrix_cuda.cu
If that works, remove test and matrix_cuda.o and
5) try that makefile again.
If that works, there are further refinements we can make.
Also your first make rule corresponds to compiling the object file matrix_cuda.o. The all make rule should come first since the first rule in the make file is the one that gets updated first when invoking the command make. GNU Make has great documentation explaining how to make simple to complex makefiles. You can check it out here:
https://www.gnu.org/software/make/manual/make.html.
Also another issue you are going to run into is that in your make recipe for the all rule, you are supposed to be linking together only object files to create the final executable. However you are trying to include matrix_blas.cpp alg.cpp test.cpp in this linking step. Instead of .cpp versions of these files they need to be .o versions (the compiled objects). Make can generate these object files for you. You just need to have a make rule and recipe for each one. For example:
matrix_blas.o: matrix_blas.cpp
$(CC) $(CXXFLAGS) -c matrix_blas.cpp -o matrix_blas.o
I want to add some commentary on this Makefile for future reference and better automation :
1. NVCC=nvcc environment variable is superfluous. There is only one compiler for NVIDIA GPUs and you would nonetheless have to change a lot of flags to compile for other architectures like AMD.
-arch=native is better suited if you want to deploy your code on multiple machines with GPUs having different architectures
-dc is the flag for separate compilation. The architecture must be specified before -dc see (with a generic Makefile): https://developer.nvidia.com/blog/separate-compilation-linking-cuda-device-code/
You should add automatic rule to avoid these typos errors :
%.o: %.cu
nvcc -dc $(CUDAFLAGS) $< -o $#
The Makefile will look for all dependencies ending by .o. If it needs to build one, it looks if it has the corresponding .cu file. I would actually remove the -dc from flags and be explicit here that I want to build object files.
$# is the name of the rule target. $< is the first prerequisite. Only one file at a time can be passed to nvcc with the -dc flag, so here $< is better than $^.
You may add the name of the executable in a variable so that you delete the same executable that you generated (and facilitate name change).
I added a .PHONY rule. This only removes the confusion that happens whenever someone writes a file named clean in the directory.
The Makefile can not differenciate between the file and the make clean rule.
CC=g++
CXXFLAGS= -fopenmp -O3 -Wextra -std=c++11
CUDAFLAGS= -std=c++11 -arch=sm_20
LIBS= -lopenblas -lpthread -lcudart -lcublas
LIBDIRS=-L/usr/local/cuda-7.5/lib64
INCDIRS=-I/usr/local/cuda-7.5/include
PROGRAM= test
%.o: %.cu
nvcc -dc $(CUDAFLAGS) $< -o $#
all: matrix_cuda.o
$(CC) -o $(PROGRAM) matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o $(LIBDIRS) $(INCDIRS) $(LIBS) $(CXXFLAGS)
.PHONY: clean
clean:
rm -rf $(PROGRAM) *.o

Compiling asm with gcc - ubuntu

I've been trying to compile some language (CISC) that my professor created which is pseudo assembly. He wanted us to make a makefile and compile the file with .asm extension using gcc.
This is the makefile:
.SUFFIXES: .asm
all:schemeCompiler
schemeCompiler:target.o
gcc -g -m32 -Wall -o schemeCompiler target.o
target.o: target.asm
gcc -m32 -g -Wall -ansi -c -o target.o target.asm
.PHONY: clean
clean:
rm -f *.o schemeCompiler
And this is the error I get:
gcc -m32 -g -Wall -ansi -c -o target.o target.asm
gcc: warning: target.asm: linker input file unused because linking not done
gcc -g -m32 -Wall -o schemeCompiler target.o
gcc: error: target.o: No such file or directory
gcc: fatal error: no input files
compilation terminated.
I've put the makefile with the asm file in the same directory
Thanks !
***We've figured out the problem , we weren't running the make command right. Also the makefile wasn't right:
.SUFFIXES: .asm
all:schemeCompiler
schemeCompiler:$#
gcc -g -m32 -Wall -o schemeCompiler $#
%: %.asm
gcc -x c -o $# $<
.PHONY: clean
clean:
rm -f *.o schemeCompiler

makefile which get also the name of the file compile

I need a makefile which get also the name of the file compile
For example:
make foo
and the makefile should compile foo.c to foo.
This is my makefile. How to change it?
all: out
out: out.o
gcc -g -m32 -Wall -o out out.o
out.o: out.c
gcc -m32 -g -Wall -ansi -c -o out.o out.c
.PHONY: clean
#Clean the build directory
clean:
rm -f *.o out
There is no direct way where you can pass arguments to the Makefile but instead you can take advantage of variables to achieve what you want. Check the modifications done to the Makefile below
NAME ?=out #Default binary generated is out if you dont pass any argument
${NAME}: ${NAME}.o
gcc -g -m32 -Wall -o ${NAME} ${NAME}.o
${NAME}.o: ${NAME}.c
gcc -m32 -g -Wall -ansi -c -o ${NAME}.o out.c
.PHONY: clean
#Clean the build directory
clean:
`rm -f *.o ${NAME}`
And you should call the Makefile by typing
$ make NAME=foo
$ make clean NAME=foo
Passing arguments directly to Make is trivially easy.
Your current makefile can be invoked with make foo, and will compile foo.c to produce foo, because Make has implicit rules for handling cases like foo.c => foo; there will be no error even though "foo" is not the target of any rule. (At least, this is the case with GNU Make 3.81, which is what I am using.)
If you want to control the choice of compiler and flags (as in your out rule), there is more than one way to do it. The simplest (though not strictly the best) is to modify a couple of variables in the makefile:
CC = gcc
CFLAGS = -g -m32 -Wall -ansi
Another option is to override the implicit rule with a pattern rule of your own:
%: %.c
gcc -g -m32 -Wall -ansi -o $# $<
If you want it to build foo.o in a separate step, you must split the rule into two rule-- and also put in a rule with no recipe to cancel Make's implicit rule:
%: %.o
gcc -g -m32 -Wall -o $# $^
%.o: %.c
gcc -m32 -g -Wall -ansi -c -o $# $<
%: %.c
Further refinements are possible, once you have mastered the basics.

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.

Resources