So I have two C files which are master.c, slave.c and then config.h and I'm trying to build a makefile for the execution of these files and I'm getting an error.
I'm using a normal terminal on MacOS and when executing make I get the following error:
ss#US3FHIM0XQ86TJG: ~/project-2[master*]$ make
gcc -o master config.h master.c -g -I -std=gnu99
clang: error: cannot specify -o when generating multiple output files
make: *** [master] Error 1
Here is what my makefile looks like:
CC = gcc
CFLAGS = -g -I -std=gnu99
all: master slave
master: config.h master.c
$(CC) -o $# $^ $(CFLAGS)
slave: config.h slave.c
$(CC) -o $# $^ $(CFLAGS)
clean:
rm master slave cstest logfile.*
Can someone spot what might be causing this issue?
Remove config.h. You can compile it on the command line and omit "config.h", ie:
gcc -o master master.c -g -I -std=gnu99
Some people like to put that -o at the end:
gcc -g -I -std=gnu99 -c master.c -o master
A more appropriate way would be:
gcc -g -I/usr/include -std=gnu99 -c master.c -o master
Generally, the -I has a path, such as -I/usr/include, but you can omit the -I as your compiler usually looks there first.
Also, you may have to tweak your Makefile and omit the config.h if it is happening when you type make.
Some little errors you can fix by compiling the object by hand (ie, as above, gcc -g -I/usr/include -std=gnu99 -c master.c -o master)
Once you edit Makefile and remove config.h, and perhaps use -I/usr/include or path to your headers, you can run:
make clean
make all
or just:
make slave
or:
make master
etc, etc
$^ is a placeholder for the list of dependencies. That is why the rule
master: config.h master.c
$(CC) -o $# $^ $(CFLAGS)
runs the command
gcc -o master config.h master.c -g -I -std=gnu99
Compiling .h produces one output, compiling .c produces another output. The compiler does not know to which of them to apply -o. The proper way is using rules
master: master.c config.h
$(CC) -o $# $< $(CFLAGS)
slave: slave.c config.h
$(CC) -o $# $< $(CFLAGS)
$< is a placeholder for the first item in the list of dependencies. These rules run gcc properly
gcc -o master master.c -g -I -std=gnu99
gcc -o slave slave.c -g -I -std=gnu99
Related
I'm trying to compile a C program on Windows for use on a linux dev board.
When I try to compile using a makefile I get this output:
$ make
arm-linux-gnueabihf-gcc -g -Wall main.c -o filetest
process_begin: CreateProcess(NULL, arm-linux-gnueabihf-gcc -g -Wall main.c -o filetest, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [filetest] Error 2
This happens whether or not a blank file called filetest is present or not in the same directory. If it is present, I can run make clean and it will remove the file.
Here is the makefile I'm using:
#
TARGET = filetest
ALT_DEVICE_FAMILY ?= soc_cv_av
SOCEDS_ROOT ?= $(SOCEDS_DEST_ROOT)
HWLIBS_ROOT = $(SOCEDS_ROOT)/ip/altera/hps/altera_hps/hwlib
CROSS_COMPILE = arm-linux-gnueabihf-
CFLAGS = -g -Wall -D$(ALT_DEVICE_FAMILY) -I$(HWLIBS_ROOT)/include/$(ALT_DEVICE_FAMILY) -I$(HWLIBS_ROOT)/include/
LDFLAGS = -g -Wall
CC = $(CROSS_COMPILE)gcc
ARCH= arm
build: $(TARGET)
#
$(TARGET):main.c
$(CC) $(LDFLAGS) $^ -o $#
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -f $(TARGET) *.a *.o *~
I used tabs in my actual makefile instead of spaces for the code block above ^^
Also, I'm working within Intel's FPGA SoC EDS for a Cyclone V board.
I have 6 programs: HOSpital.c, GenPazienti.c, Triage.c, Paziente.c, Prestazione.c and Reparto.c.
No one of them includes any other.
How can i do the makefile?
I tried with:
all: HOSpital GenPazienti Paziente Prestazione Reparto Triage
HOSpital: HOSpital.o
gcc -o HOSpital HOSpital.c
HOSpital.o: HOSpital.c
gcc -c HOSpital HOSpital.c
GenPazienti: GenPazienti.o
gcc -o GenPazienti GenPazienti.c
GenPazienti.o: GenPazienti.c
gcc -c GenPazienti GenPazienti.c
Paziente: Paziente.o
gcc -o Paziente Paziente.c
Paziente.o: Paziente.c
gcc -c Paziente Paziente.c
Prestazione: Prestazione.o
gcc -o Prestazione Pretazione.c
Prestazione.o: Prestazione.c
gcc -c Prestazione Prestazione.c
Reparto: Reparto.o
gcc -o Reparto Reparto.c
Reparto.o: Reparto.c
gcc -c Reparto Reparto.c
Triage: Triage.o
gcc -o Triage Triage.c
Triage.o: Triage.c
gcc -c Triage Triage.c
clean:
rm -f *.o
But if i change something and i type "make" i get the error:
"Program_name: linker input file unused because linking not done"
Lets take a single example:
gcc -c HOSpital HOSpital.c
This will attempt to use HOSpital as an input file.
Either use the correct option to name the output file, -o, and name it correctly. Like in
gcc -c -o HOSpital.o HOSpital.c
Or don't specify the output file name at all, then the compiler will use the input source file and change the .c suffix to .o. Like in
gcc -c HOSpital.c
It's the same problem all over.
Not that it matters in the end, the rule is used so the object file will be built, but you don't actually use the object file:
gcc -o HOSpital HOSpital.c
Here you use the source file directly to create the program. I think you meant to use
gcc -o HOSpital.o HOSpital.o
And as with the previous problem, you make this mistake all over.
Finally some general tips.
First, build with more warnings enabled. It will help you in the long run to find mistakes in the code, and will help find out places where there's possible undefined behaviors. I recommend at least adding -Wall -Wextra -pedantic.
Then you don't need to list all the object files and their rules explicitly in the makefile. The make program already knows how to make e.g. object files through implicit rules.
That last point means you can shorten down the makefile to something like
CFLAGS = -Wall -Wextra -pedantic -pipe
LD = gcc
LDFLAGS = -pipe
HOSpital: HOSpital.o
$(LD) $(LDFLAGS) -o $# $^
GenPazienti: GenPazienti.o
$(LD) $(LDFLAGS) -o $# $^
Paziente: Paziente.o
$(LD) $(LDFLAGS) -o $# $^
Prestazione: Prestazione.o
$(LD) $(LDFLAGS) -o $# $^
Reparto: Reparto.o
$(LD) $(LDFLAGS) -o $# $^
Triage: Triage.o
$(LD) $(LDFLAGS) -o $# $^
clean:
-rm -f *.o
The variable $# is the target of the rule, and the variable $^ is all prerequisites. For e.g.
HOSpital: HOSpital.o
the variable $# is HOSpital and $^ is HOSpital.o.
I have this simple structure:
.
test.c
plugins/a.c
plugins/b.c
plugins/c.c
And I'm compiling this with a bash script:
gcc -o test test.c -std=gnu99 -ldl -Wl,--export-dynamic
gcc -c plugins/a.c -o plugins/a.o -pedantic -g -Wall -std=c99 -fpic -I.
gcc plugins/a.o -o plugins/a.so -shared
...same for b and c...
Anyways, I want to port that to a Makefile. Here's what I have:
CC = gcc
PLUGIN_DIR = plugins
PLUGINS_C = $(wildcard $(PLUGIN_DIR)/*.c)
PLUGINS_O = $(patsubst %.c,%.o, $(PLUGINS_C))
new: clean all
all: test plugins
test: test.o
$(CC) -o $# $^ -std=gnu99 -ldl -Wl,--export-dynamic
plugins:
???
$(PLUGIN_DIR)/*.c:
$(CC) -c $(PLUGIN_DIR)/$# $^ -pedantic -g -Wall -std=c99 -fpic -I.
$(PLUGIN_DIR)/*.o:
$(CC) $# $^ -shared
clean:
rm -rf test *.o *.a plugins/*.o plugins/*.so
But this won't work as the plugins rule is empty and I really can't find out what should I write in there to make it compile all the plugins inside the plugins folder.
Also, I'm not sure if I messed up things with $# and $^.
There are a number of problems with your makefile before we get to your question.
The wildcard character in a rule target is % not * (in lines like your $(PLUGIN_DIR)/*.c:).
Rules specify how the files named by the target/target pattern are built. So your %.c rule is telling make how to build .c files (which I trust you'll agree) isn't exactly what you meant. (Similarly your %.o rule is telling make how to build .o files).
You don't have any prerequisites (right-hand side of : in a target line) listed for your build rules so make cannot intelligently rebuild targets as their prerequisites are changed (and will never rebuild them instead).
To get to your question, you likely don't want anything in the body of the plugins target. Instead you want to list the desired plugins output files (the .so files) as the prerequisites of the plugins target. (You will also want to include .PHONY: plugins in your makefile to tell make that plugins is not a real file but instead a phony target.)
Your %.so rule wants to be more like:
$(PLUGINS_DIR)/%.so: $(PLUGINS_DIR)/%.o
$(CC) $^ -o $# -shared
and your %.o rule wants to be more like:
$(PLUGINS_DIR)/%.o: $(PLUGINS_DIR)/%.c
$(CC) -c $< -o $# -pedantic -g -Wall -std=c99 -fpic -I.
When I do practice , I have a practice path.
Under this path , I have an Include path named myInclude (I have some useful function is this folder and I always use it.)
And a code path named symbol_try.I always make add new folder (with a c file and main function in it) in symbol_try and compile it.
Each time I have to compile it by gcc in terminal .Its a boring work , so I write a Makefile.
Here is an example:
the main Makefile in practice path:
FOBJS=
include myInclude/Rule.mk
include symbol_try/codeList_13.1/Rule.mk
symbol:$(FOBJS) <==What exactly I what . A executable file.
gcc -o symbol $(FOBJS) -pthread -lpthread
subsystem:
cd myInclude/ && $(MAKE)
cd symbol_try/codeList_13.1/ &&$(MAKE)
clean:
rm -rf symbol
In the myInclude/Rule.mk
FOBJS+=myInclude/otherFunction.o myInclude/error.o \
myInclude/unit.o myInclude/unitTest.o\
In the symbol_try/codeList_13.1/Rule.mk
FOBJS+=symbol_try/codeList_13.1/codeList_13.1.o
In myInclude/Makefile:
OBJS=otherFunction.o error.o unit.o unitTest.o
ALL:$(OBJS)
.PHONY:ALL
$(OBJS):%.o:%.c
gcc -c $< -o $#
clean :
otherFunction.o error.o unit.o
In symbol_try/codeList_13.1/Makefile:
codeList_13.1.o:codeList_13.1.c
gcc -c codeList_13.1.c
Well.That can work. But as you see , I have to write a Rule.mk(to initialize the FOBJS) and a Makefile for each folder.
I am new for make , I want find a way more concise , witch I only need write one Makefile for each folder and a main Makefile.No Rule.mk any more.
PS: I always change the code in myInclude ,so I don't want to build it a library.
Thanks for any help.
Here's one way you can do it with just one Makefile:
CC = gcc
CPPFLAGS += -I myInclude/ (1)
CFLAGS += -std=c99 -Wall (2)
VPATH = myInclude/ \ (3)
symbol_try/codeList_13.1/
symbol: otherFunction.o error.o unit.o unitTest.o codeList_13.1.o (4)
$(CC) -o $# $^ (5)
.PHONY : clean
clean:
rm -f symbol *.o
Note that make knows how to build C files and has some standard macros: CC, CPPFLGAS, CFLAGS
Add the include paths of your headers. You presumably have some headers for the individual object files in the myInclude directory.
Put the compiler flags here.
Add the paths to the source files you want to build.
List the object files that the executable depends upon
As there is no file called symbol.c you need to tell make how to create symbol.o with a rule. $# means the target ('symbol', here), and $^ means all of the prerequisites (the object files listed).
Here's a list of all of the files in my test directories for this:
$ find . -type f
.
./Makefile
./myInclude/error.c
./myInclude/header.h
./myInclude/otherFunction.c
./myInclude/unit.c
./myInclude/unitTest.c
./symbol_try/codeList_13.1/codeList_13.1.c
And the build output:
$ make
gcc -std=c99 -Wall -I myInclude/ -c -o otherFunction.o myInclude/otherFunction.c
gcc -std=c99 -Wall -I myInclude/ -c -o error.o myInclude/error.c
gcc -std=c99 -Wall -I myInclude/ -c -o unit.o myInclude/unit.c
gcc -std=c99 -Wall -I myInclude/ -c -o unitTest.o myInclude/unitTest.c
gcc -std=c99 -Wall -I myInclude/ -c -o codeList_13.1.o symbol_try/codeList_13.1/codeList_13.1.c
gcc -o symbol otherFunction.o error.o unit.o unitTest.o codeList_13.1.o
Why don't you create a library from the objects in myInclude and do the linking in the Makefile in your code path (symbol_try/codeList_13.1). The latter is better anyway because the needed libraries (-pthread -lpthread in your case) might change as well for some other code.
The main Makefile now would have got nothing to do but call make in all needed subdirectories.
In each folder have a makefile with
SOURCES=sample.c sampletest.c
OBJECTS=$(SOURCES:%.c=$(OBJDIR)/%.o)
all: $(OBJECTS)
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -o $# $<
In the root directory of a project, create a makefile with a rule to compile every sub-folder like the below.
Dirs= path-to-rootdir
objs:
set -e ; \
for i in $(Dirs) ; do \
$(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS_MODULE)" LDFLAGS="$(LDFLAGS)" OBJDIR="$(OBJDIR)" -C $$i; \
done
And then you could use it build the executable by adding a rule
EXE: objs
$(CC) -L./Path1 $(LIB_PATH) -llib1 -o $(EXE_NAME) $(wildcard $(OBJDIR)/*.o)
Hope this helps!!!
I've tried to get my makefile to compile a file that requires -std=c99 to run. In this case, its to get a "for-loop" through.
This is my code, (its been used "tab" before "$(CC)" ):
CC = gcc
CFLAGS = -c -std=c99
...
Download.o : Download.c
$(CC) $(CFLAGS) Download.c
Download.c contains methods used to download elements from the web
Error message
$ make
gcc -c -std=c99 Download.c
gcc Download.c -o Program
Download.c: In function ‘downloadImageparts’:
Download.c:11:2: error: ‘for’ loop initial declarations are only allowed in C99 mode
Download.c:11:2: note: use option -std=c99 or -std=gnu99 to compile your code
Download.c:13:3: error: ‘for’ loop initial declarations are only allowed in C99 mode
make: *** [comp] Error 1
Attemt to debug
If I run gcc -c -std=c99 Download.c in terminal it works fine.
This problems appears when run in Linux.
SOLVED:
I created a dummy project to show my lecturer, in an attempt to solve my problem. In the dummy project all works fine with the code described. For some reason my code works on place but not in the other. If someone reading this having the same problem as me and would like to see an example project. let me know and I'll write the code here. Thanks
You're looking at the wrong rule. Download.c is actually compiling fine, but the linking stage is wrong.
$ make
gcc -c -std=c99 Download.c # Compile
gcc Download.c -o Program # Link
Fix the make rule that links the program. It should probably look something like this:
Program: a.o b.o c.o
$(CC) $(LDFLAGS) -o $# $^ $(LIBS)
While you're at it, I suggest a more complete Makefile will look something like this:
all: Program
clean:
rm -f Program *.o
.PHONY: all clean
# -c is implicit, you don't need it (it *shouldn't* be there)
# CC is also implicit, you don't need it
CFLAGS := -std=c99 -g -Wall -Wextra
Program: a.o b.o c.o
$(CC) $(LDFLAGS) -o $# $^ $(LIBS)
# Make will automatically generate the necessary commands
# You just need to name which headers each file depends on
# (You can make the dependencies automatic but this is simpler)
a.o: a.c header.h
b.o: b.c header.h header2.h
c.o: c.c header.h
Examples of how to do it wrong
Linker flags are actually fairly touchy! Be sure to type in the line above exactly as I have written it, and don't assume that what you've written is equivalent. Here are some examples of slightly different commands that are wrong and should not be used:
# WRONG: program must depend on *.o files, NOT *.c files
Program: a.c b.c c.c
$(CC) ...
# WRONG: -c should not be in CFLAGS
CFLAGS := -c -std=c99
Program: a.o b.o c.o
# WRONG: $(CFLAGS) should not be here
# you are NOT compiling, so they do not belong here
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $^ $(LIBS)
# WRONG: $(LIBS) MUST come at the end
# otherwise linker may fail to find symbols
$(CC) $(LDFLAGS) -o $# $(LIBS) $^
# WRONG: do not list *.o files, use $^ instead
# otherwise it is easy to get typos here
$(CC) $(LDFLAGS) -o $# a.o b.o c.o $(LIBS)
# WRONG: $(LDFLAGS) must be at the beginning
# it only applies to what comes after, so you
# MUST put it at the beginning
$(CC) -o $# $(LDFLAGS) $^ $(LIBS)
# WRONG: -c flag disables linking
# but we are trying to link!
$(CC) $(LDFLAGS) -c -o $# $^ $(LIBS)
# WRONG: use $(CC), not gcc
# Don't sabotage your ability to "make CC=clang" or "make CC=gcc-4.7"
gcc $(LDFLAGS) -o $# $^ $(LIBS)
# WRONG: ld does not include libc by default!
ld $(LDFLAGS) -o $# $^ $(LIBS)
I see the same results if I use spaces instead of tabs inside the makefile, and the output of make shows that the rule isn't being used:
$ make
cc -c -o Download.o Download.c
Download.c: In function ‘main’:
Download.c:4:3: error: ‘for’ loop initial declarations are only allowed in C99 mode
Download.c:4:3: note: use option -std=c99 or -std=gnu99 to compile your code
make: *** [Download.o] Error 1
Try a tab before the line starting with gcc.
After seeing the update to the original question:
$ make
gcc -c -std=c99 Download.c
gcc Download.c -o Program
The first (compile) line shows no errors.
It's the second line, which re-compiles Download.c, that fails.
I think you want to link the .o files to create the executable Program here, as Dietrich Epp suggests.