g++: fatal error: cannot specify -o with -c, -S or -E with multiple files - compilation

I am trying to compile a library file using other library files. I am using the following line in my makefile to create gameobject.o:
lib/gameobject.o: src/gameobject.cpp src/vector.hpp lib/objectevent.o lib/sprite.o
g++ $^ -c -o $# $(SFML_FLAGS)
All the dependencies comile correctly, but I get the following error when it tries to compile gameobject.o:
g++: fatal error: cannot specify -o with -c, -S or -E with multiple files
I'm still a bit new to using make/separating compilation, so I'm not quite sure what I should do. Do I just have to compile it without setting an output? Do I have to compile gameobject.o without using any of my other .o files? If that's true, wouldn't compile times get pretty big for large objects if you can't compile libraries with other libraries? Or am I just reading this error completely wrong?

You're not building a library file here. A .o file is an object file. Typically there is one object file per source file. When you use the compiler's -c option, it takes a single source file and compiles it into a single object file. You cannot add other object files into an existing object file, so adding both .o and .cpp files into the same compiler line with -c is not going to work.
If you want to create a library, that would be something like libfoo.a (the "a" here stands for "archive"). If you want to create an executable you can do that as well.
You need to be more clear about exactly what result you want before we can describe how to get it.

I had the same problem after I combined some projects of a solution to a single one. I find out there was tow .cpp files with same names and after I did rename one of them It solved.

You can create only one object .o file from one source file.
If you are using makefile to build the project. Make sure you are doing $< instead of $^
# Correct one
%.o: %.cpp
$(CPP) $(CFLAGS) -c -o $# $<
# InCorrect one
%.o: %.cpp
$(CPP) $(CFLAGS) -c -o $# $^

Related

How do I assemble multiple assembly files into multiple object files with a Makefile?

I want to be able to turn all the *.asm files in a folder to *.o files. For example, if I have header.asm and main.asm, I want header.o and main.o. Nasm can only assemble 1 input file to 1 output file.
I have tried this:
%.o : %.asm
nasm -f elf64 $(patsubst %.o,%.asm,$#) -o $#
along with multiple other things but to no success.
Somewhere you have to tell make what files you want to assemble. A pattern rule is just a template for how to build a .o from a .asm. It's not an instruction that says "go find all .asm files and turn them into .o files". It's a template that says, IF you want to build a .o file, and you can find a .asm file, then here's how you can turn the latter into the former.
So, you need a pattern rule to describe how to build things:
%.o : %.asm
nasm -f elf64 $< -o $#
then you also need a list of the things you want to build; say:
all: foo.o bar.o baz.o
(since you haven't told us anything about the names of the .asm files you want to build I just used random names).

GNU make generate assembly first, them compile them to .o and link

SOURCE=a.c b.c c.c
ASM=$(patsubst %.c,%.s, $(SOURCE))
all:%.o
gcc -o test $^
$(ASM):%.c
gcc -S -o $# $<
%.o:%.s
gcc -c -o$# $<
I want to generate assembly code (.s) first, then compile the assembly code to object (.o), then link them.
But it seems above makefile code does not work. What is the correct code?
When asking questions, does not work is never very useful... if it worked you probably wouldn't be asking a question! :-) Instead you should always show the command you ran and the output you received (or at least the failing part of the output if it's long). Please cut and paste the actual text rather than paraphrasing messages. Also, including the version of the make program you're using (make --version) and the platform you're running on is often helpful.
Luckily this time we can figure out the problem without this information:
This:
$(ASM):%.c
gcc -S -o $# $<
where ASM is a.s b.s c.s, is not a pattern rule because the targets don't contain a pattern character %. That means the prerequisite %.c is not treated as a pattern, but as an actual file name, literally %.c which obviously doesn't exist.
Similarly, this:
all: %.o
has the same problem: all is a target, so this depends on the literal file named %.o which doesn't exist, and can't be created.
Also as a general rule every recipe that creates a target must create the actual target you told make it would, so this all rule is wrong because the target name is all but the recipe creates the target test.
Finally, it's a very bad idea to name your program test because test is a common UNIX program and a shell built-in, so if you run test it won't do the right thing (if you run ./test it will work).
You want to have all depend on the program you want to build, say mytest, and mytest should depend on the actual .o files:
all: mytest
mytest: $(SOURCE:.c=.o)
gcc -o $# $^
Next, you need to define a pattern rule that knows how to create an assembly file from a source file:
%.s : %.c
gcc -S -o $# $<
That, along with your other pattern rules, is all you need: make will figure it all out from that.
Finally, make has a built-in rule that tells it how to build object files directly from source files. It's best to get rid of this to force make to use your rules; add this to your makefile to delete it:
%.o : %.c

How to create a makefile that will place object code in different folder

I am very new to Makefile. I had build the following makefile(Which don't work).I wan't put genarated object codes in differnt folder(the folder is in current directory).
$ ls
main.cpp Makefile object_code Time.cpp Time_.h
how can I do this ??
VER = Debug
CC = g++
OBJECTFIELS = ./object_code/main.o ./object_code/Time.o
../$(VER)/main: $(OBJECTFIELS)
$(CC) $(OBJECTFIELS) -o $#
$(OBJECTFIELS): Time_.h
./object_code/main.o: main.cpp
./object_code/Time.o: Time.cpp
clean:
rm $(OBJECTFIELS) main
this is error.
$ make
g++ ./object_code/main.o ./object_code/Time.o -o ../Debug/main
g++: error: ./object_code/main.o: No such file or directory
g++: error: ./object_code/Time.o: No such file or directory
g++: fatal error: no input files
compilation terminated.
Makefile:8: recipe for target '../Debug/main' failed
make: *** [../Debug/main] Error 1
please this is last question.
I don't see how you can possibly get that output given the makefile you've posted here.
Either the object files already exist in which case the link will succeed rather than printing that error.
Or the object files don't exist in which case make will complain because it doesn't know how to make them. There must be some difference between the makefile you're using and the one you've posted here.
In any event, make knows how to build a file foo.o from a file foo.cpp for any string foo. There's a built-in rule that tells it how to do that.
But, make doesn't know how to build a file ./object_code/foo.o from a file foo.cpp, regardless of foo. There's no built-in rule that tells make how to build object files in some random other directory. If you want make to do that, you'll have to tell it how. You should remove the lines:
./object_code/main.o: main.cpp
./object_code/Time.o: Time.cpp
and replace them with a pattern rule describing how to build object files into the object_code directory (I'm using CXX as the compiler variable here: by convention CC is the C compiler and CXX is the C++ compiler, and you should always stick with convention unless there's a good reason not to):
VER = Debug
CXX = g++
OBJECTFIELS = ./object_code/main.o ./object_code/Time.o
../$(VER)/main: $(OBJECTFIELS)
$(CXX) $(OBJECTFIELS) -o $#
$(OBJECTFIELS): Time_.h
./object_code/%.o : %.cpp
$(CXX) -c -o $# $<
clean:
rm $(OBJECTFIELS) main

C Makefile - recompile only changed files

Hello I have a shared library libnsd.so (made up of nsd.c,nsd.h,nd.c,nd.h) linked to main file.
My question is how to write the makefile so that it recompiles only those source files that have been changed.
I have read some topics about this but got somewhat confused, I'm a beginner programmer.
My makefile code so far:
CC=gcc
all : lib alll
alll : main.c
$(CC) main.c -o main -L. libnsd.so
lib : nsd.c nsd.h nd.c nd.h
$(CC) -c -fPIC nsd.c -o nsd.o
$(CC) -c -fPIC nd.c -o nd.o
$(CC) -shared -Wl,-soname,libnsd.so -o libnsd.so nsd.o nd.o
clean:
rm main libnsd.so nd.o nsd.o
Makefiles have the concept of build targets. The build targets are, really, all the intermediate as well as the final files and, by the way they are written, they can be made to use dependencies.
A sample solution for your makefile:
CC=gcc
all: main
main: main.c libnsd.so
$(CC) main.c -o main -L. libnsd.so
libnsd.so: nsd.o nd.o
$(CC) -shared -Wl,-soname,libnsd.so -o libnsd.so $#
%.o: %.c nsd.h nd.h
$(CC) -c -fPIC $< -o $#
A few things to note:
You should properly correct my dependencies on the object file creation (since I consider that each of the C files depends on both of the headers).
You may wish to note the wildcard construction I have used...
If there was nothing special with some of these commands I could have left default commands work. Do note that I have used $< for the first dependency and $# for the output in the wildcard rule.
I haven't copied the clean rule, since it was written correctly in the question itself.
Each of the targets (besides the "phony" target all) creates a file with the same name: The target libnsd.so creates a file with the name libnsd.so. The target main creates a file with the name main.
As a dependency of a target changes date so that the dependency is newer than the output, make will recreate the target, as well as other targets that depend on it. But if you have a target that is not mapped to any output file, that target is always called (in our code, the all target is always called but thankfully it has no commands and it depends only on actual files which may or may not need being recreated)
Do note that GNU Make doesn't need to have compiling in particular. The creation of an output file can happen by any means, and indeed I have seen a target create a .cpio.gz archive. But if that archive is older than any of the dependencies (the folder it would pack in) then it would be recreated, according to make.

gcc / make - creating make files for creating assembly and linking

To perform an experiment I want to modify the assembly code of the OpenWRT Project (by inserting NOPs between the regular, meaningful code).
Thous I need to create the assembly files (.s files) by compiling with gcc's -S flag in the first run, execute a shell script modifying the assembly files and call the linker in the third step to create the executable binaries. Beside step 2, is there a way to accomplish steps 1 & 3 by an appropriate make file modification/configuration, i.e. create one make file for compiling (creating .s files) and another to conduct linking?
Thanks for enlightenment &
Happy a new year! :)
use this syntax:
target [target...] : [dependent ....]
[ command ...]
example:
%.S: %.c
$(CC) -S $# -c $<
%.o: %.S
$(CC) -o $# -c $<
which means to build the target foo.o make should build foo.S and for foo.S build foo.c
$# means target name
$< means targets first dependency

Resources