error with makefile (executables) - c

Hi after a previous problem with not having makedepend installed (now solved), I now have the following error when trying to run my makefile:
$ make
makedepend -- -- -I /usr/include/linux -I include
cp executables
cp: missing destination file operand after `executables'
Try `cp --help' for more information.
make: *** [executables] Error 1
and here is my makefile:
CMDLINE_SRC=$(wildcard commandLine/*.c)
CMDLINE_OBJS = $(CMDLINE_SRC:.c=.o)
EXECUTABLES = $(CMDLINE_SRC:.c=)
LIB_SRC=$(wildcard c/*.c)
LIB_OBJ = $(LIB_SRC:.c=.o)
LIB_OUT = lib/libclinrisk.a
INCLUDES = -I include
# compiler
CC = gcc
CCFLAGS =
LDFLAGS =
# library paths
LIBS = -Llib -lclinrisk -lm
.SUFFIXES: .c
default: dep executables
executables: $(EXECUTABLES)
cp $(EXECUTABLES) executables
$(EXECUTABLES): $(LIB_OUT)
.c:
$(CC) $(INCLUDES) $(LDFLAGS) $< -o $# $(LIBS)
.c.o:
$(CC) $(INCLUDES) $(CCFLAGS) -c $< -o $#
$(LIB_OUT): $(LIB_OBJ)
ar rcs $(LIB_OUT) $(LIB_OBJ)
depend: dep
dep:
makedepend -- $(CFLAGS) -- -I /usr/include/linux $(INCLUDES) $(LIB_SRC)
clean:
rm -f $(LIB_OBJ) $(LIB_OUT) Makefile.bak
rm -f $(CMDLINE_OBJ) $(CMDLINE_PROGS)
rm -f executables/*
what is the problem here? I am new to makefiles! will try figure this out in the meantime.
The problem looks like it's to do with:
cp $(EXECUTABLES) executables
however I'm unaware of a correct pathway to executables...
Thanks.

Nothing in your Makefile code sets the EXECUTABLES variable, so it substitutes to an empty string, which calls cp with just a single argument, thus generating the error.

Related

"clang: error: cannot specify -o when generating multiple output files" fix

I'm trying to compile my C project using clang (I'm on MacOS Monterry) and a Makefile, but I keep getting the same error from clang in the command line:
> make
gcc -c src/ji.c src/main.c -o src/ji.o
clang: error: cannot specify -o when generating multiple output files
make: *** [src/ji.o] Error 1
These are the only files I have in the project so far:
src/main.c
src/ji.c
include/ji.h
The Makefile looks like this:
cc = gcc
src = $(wildcard src/*.c)
obj = $(src:.c=.o)
exec = ji
$(exec): $(obj)
$(cc) -Iinclude $< -o build/$#
%.o: %.c
$(cc) -c $(src) -o $#
clean:
-rm src/*.o
-rm ji
From YouTube videos I've seen, this should be the ideal Makefile for the project but no matter what I change I get the error.
There are a few issues:
-Iinclude needs to be on the %.o: %.c rule command
In %.o: %.c, we don't want $(src) but rather $<
We want patsubst to get the .o list obj
The $(exec) target doesn't match the -o option
The clean doesn't match the placement of the executable
Here's a refactored version (e.g. one way to do this--there are others):
cc = gcc
src = $(wildcard src/*.c)
obj = $(patsubst %.c,%.o,$(src))
exec = build/ji
$(exec): $(obj)
mkdir -p build
$(cc) $^ -o $#
%.o: %.c
$(cc) -c $< -o $# -Iinclude
clean:
rm -f src/*.o
rm -fr build
Here's the output of make:
gcc -c src/ji.c -o src/ji.o -Iinclude
gcc -c src/main.c -o src/main.o -Iinclude
mkdir -p build
gcc src/ji.o src/main.o -o build/ji
Here's the output of make clean:
rm -f src/*.o
rm -fr build

make: create a test binary for each file in test directory

I have a simple structure as below for a small library I'm building.
I want make build to build the library (libproj.a) from sources under ./source
I want make build_test to build every source file under ./test prefixed with test_ into it's own binary
I can build the library libproj.a just fine, but can't figure out how to build the tests. I'm currently getting the following linker error when attempting to build /cygdrive/d/Source/proj/build/obj/test_proj.o:test_proj.c:(.text+0x15): undefined reference to 'test'.
Directory structure
+---build
| +---lib
| +---obj
| \---test
+---include
| \---proj
+---source
\---test
Makefile
PROJECT = proj
LIBNAME = lib$(PROJECT).a
CFLAGS = -Wall -Wextra -O0
DIR_ROOT = $(abspath .)
DIR_SRC_LIB = $(DIR_ROOT)/source
DIR_SRC_TEST = $(DIR_ROOT)/test
DIR_BLD_OBJ = $(DIR_ROOT)/build/obj
DIR_BLD_LIB = $(DIR_ROOT)/build/lib
DIR_BLD_TEST = $(DIR_ROOT)/build/test
LST_OBJ_LIB = $(patsubst $(DIR_SRC_LIB)/%.c, $(DIR_BLD_OBJ)/%.o, $(wildcard $(DIR_SRC_LIB)/*.c))
LST_OBJ_TEST = $(patsubst $(DIR_SRC_TEST)/%.c, $(DIR_BLD_OBJ)/%.o, $(wildcard $(DIR_SRC_TEST)/*.c))
LST_BIN_TEST = $(patsubst $(DIR_SRC_TEST)/%.c, $(DIR_BLD_TEST)/%, $(wildcard $(DIR_SRC_TEST)/test_*.c))
INCLUDES = -I $(DIR_ROOT)/include
clean:
$(RM) $(LST_OBJ_LIB)
$(RM) $(LST_OBJ_TEST)
build:
$(info build)
build-test: $(LST_BIN_TEST)
$(info build-test)
run-test:
$(info run-test)
install:
$(info install)
$(LIBNAME): $(LST_OBJ_LIB)
$(AR) rvs $(DIR_BLD_LIB)/$# $^
$(DIR_BLD_OBJ)/%.o: $(DIR_SRC_LIB)/%.c
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
$(DIR_BLD_TEST)/%: $(DIR_BLD_OBJ)/%.o $(LIBNAME)
$(CC) $(LDFLAGS) -L $(DIR_BLD_LIB) -l $(PROJECT) $< -o $#
$(DIR_BLD_OBJ)/%.o: $(DIR_SRC_TEST)/%.c
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
My guess is that this line:
$(CC) $(LDFLAGS) -L $(DIR_BLD_LIB) -l $(PROJECT) $< -o $#
is wrong. You're passing to the compiler (I'm assuming gcc) the libraries before the object files. If your compiler acts as gcc does, the code in the libraries is getting discarded because it hasn't been referenced yet when it parses them see -l option documentation.
It should be
$(CC) $(LDFLAGS) -L $(DIR_BLD_LIB) $< -l $(PROJECT) -o $#
(Note the changed position of $<)
Furthermore, remeber that the order of libraries is important: see this excellent explanation.

makefile exit with no reason when compile .pc and .c at the same time. very strange

I am using pro*c in AIX,I want make my .pc file compile to a .so libary. And link it. This is my directory:
ls
connect.pc func.c get_log.pc main.c makefile sql_err.pc
This is my makefile:
#Makefile
CC = cc -g -brtl
CFLAGS = -g -c
ESQL = proc
RM = rm -f
MYHOME = /home/xxx
OBJ = main.o func.o
LIBOBJ = get_log.o connect.o sql_err.o
DBINC = -I$(ORACLE_HOME)/precomp/public
DBLIB = -L$(ORACLE_HOME)/lib -lclntsh
INCLUDE = -I$(MYHOME)/include
.SUFFIXES: .pc .c .o
.pc.o:
$(ESQL) include=$(MYHOME)/include iname=$*.pc
$(CC) -o $*.o $(CFLAGS) $*.c $(INCLUDE) $(DBINC) $(DBLIB)
$(RM) $*.c
$(RM) $*.lis
libmydb.so:$(LIBOBJ)
$(CC) -qmkshrobj -o $# $(LIBOBJ) $(DBLIB)
mv $# $(MYHOME)/lib
query:$(OBJ)
cc -o $# $(OBJ) -L$(MYHOME)/lib -lmydb
mv $# $(MYHOME)/bin
func.o:func.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
main.o:main.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
clean:
rm -f *.o *.lis
when I make I get this:
.......
cc -g -brtl -o sql_err.o -g -c sql_err.c -I/home/xxx/include -I/oracle/product/10.2.0/precomp/public -L/oracle/product/10.2.0/lib -lclntsh
rm -f sql_err.c
rm -f sql_err.lis
cc -g -brtl -qmkshrobj -o libmydb.so get_log.o connect.o sql_err.o -L/oracle/product/10.2.0/lib -lclntsh
mv libmydb.so /home/xxxlib
when it done mv libmydb.so ,it exit!!!without wrong message.why?? I also need my .c to compile to .o and finally to an executable file query link libmydb.so.
when I change the squeuce like this put .c.o before .pc.o:
query:$(OBJ)
cc -o $# $(OBJ) -L$(MYHOME)/lib -lmydb
mv $# $(MYHOME)/bin
func.o:func.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
main.o:main.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
.pc.o:
$(ESQL) include=$(MYHOME)/include iname=$*.pc
$(CC) -o $*.o $(CFLAGS) $*.c $(INCLUDE) $(DBINC) $(DBLIB)
$(RM) $*.c
$(RM) $*.lis
libmydb.so:$(LIBOBJ)
$(CC) -qmkshrobj -o $# $(LIBOBJ) $(DBLIB)
mv $# $(MYHOME)/lib
it give this message,although I have libmydb.so last step:
prepaid(wmfe)/home/xxx/src>make
cc -g -brtl -c -g -c main.c -I/home/xxx/include
cc -g -brtl -c -g -c func.c -I/home/xxx/include
cc -o query main.o func.o -L/home/xxx/lib -lmydb
ld: 0706-006 Cannot find or open library file: -l mydb
ld:open(): A file or directory in the path name does not exist.
make: 1254-004 The error code from the last command is 255.
Stop.
I can't handle this ,very strange,Help!!
By default make will make the first rule in your makefile, but it must not start with a dot. So the default rule in your makefile is libmydb.so and that is being built.
That rule is only dependent on the LIBOBJ and OBJ is not a dependency so it doesn't care about those. It doesn't exit with no reason, it exits because it has done the job you defined for it. There is no error to report.
If you change the order then the default rule is changed and it tries to compile query. This has no dependencies to the library, so it doesn't try to compile that.
If you want to compile everything you should have, for example, a rule all that lists the dependencies. In this case probably libmydb.so and query at least, in correct order. If this is the first rule it will be the default and your compilation will succeed.

Adding a library to my makefile

I have set up a makefile that takes the sources main.c, word.c, and trim.c
I also used a library which is called linkedList.a, however even after adding it it does not build as I keep getting undefined references to functions within linkedlist.
The following is my makefile code:
SHELL = /bin/sh
SRCDIR = .
CC = gcc
YACC = bison -y
CDEBUG = -g
COMPLIANCE_FLAGS =
CFLAGS = $(COMPLIANCE_FLAGS) $(CDEBUG) -I. -I$(SRCDIR)
LDFLAGS = -g
LIBRARY_FILES = linkedList.a
linkedList.a: $(LIBRARY_FILES).o
$(RM) -f $(output)
$(AR) cr $(output) $(inputs)
ranlib $(output)
############################################################################################################
# List your sources here.
SOURCES = main.c word.c trim.c
############################################################################################################
############################################################################################################
# list the name of your output program here.
EXECUTABLE = wordCounter
############################################################################################################
# Create the names of the object files (each .c file becomes a .o file)
OBJS = $(patsubst %.c, %.o, $(SOURCES))
include $(SOURCES:.c=.d)
all : $(OBJS) $(EXECUTABLE)
$(EXECUTABLE) : $(OBJS)
$(CC) -o $(EXECUTABLE) $(OBJS)
%.o : %.c #Defines how to translate a single c file into an object file.
echo compiling $<
echo $(CC) $(CFLAGS) -c $<
$(CC) $(CFLAGS) -E $< > $<.preout
$(CC) $(CFLAGS) -S $<
$(CC) $(CFLAGS) -c $<
echo done compiling $<
%.d : %.c #Defines how to generate the dependencies for the given files. -M gcc option generates dependencies.
#set -e; rm -f $#; \
$(CC) $(COMPLIANCE_FLAGS ) -M $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
clean : # Delete any and all artifacts from the build. The only thing which is kept is the source code.
rm -f *.o
rm -f *.preout
rm -f *.s
rm -f *.S
rm -f *d
rm -f $(EXECUTABLE)
I feel I added the proper items in the proper places. My best guess is that my library_files is somehow wrong?
Your $(EXECUTABLE) rule doesn't mention the library, it just tries to link main.o, word.o and trim.o. So we must rewrite that rule.
First try this from the command line (because we can't do something with Make until we know how to do it without Make):
gcc -o wordCounter main.o word.o trim.o -L. -llinkedList
If this works, then we can write the rule:
$(EXECUTABLE) : $(OBJS) linkedList.a
$(CC) -o $# $(OBJS) -L. -llinkedList
If it doesn't, we'll have to tweak it a little. And some further refinements are possible, once we have the makefile working.
The "all:" line needs enhancement and, yes, LIBRARY_FILES needs changing/splitting. You have an OBJS variable for the executable, but nothing similar for the library. Actually, a bit more to do, as follows ...
(1) Currently, you have one library, but let's go for two:
LIBRARY_FILES += lib1.a
LIBRARY_FILES += lib2.a
(2) We now need two variables, similar to your OBJS, but one for each library:
LIBOBJS1 += abc.o def.o
LIBOBJS2 += ghi.o jkl.o
(3) We now need two rules, one for each library, similar to your rule for your library, but different [Note that most modern "ar" programs do their own ranlib--YMMV]:
lib1.a: $(LIBOBJS1)
ar crv $# $(LIBOBJS1)
lib2.a: $(LIBOBJS2)
ar crv $# $(LIBOBJS2)
(4) Now, change the rule for the executable itself:$(EXECUTABLE): $(OBJS) $(LIBRARY_FILES)
$(CC) -o $(EXECUTABLE) $(OBJS) $(LIBRARY_FILES)
(5) Now, we need to change the "all:" line. With the other rule changes, this can be simplified to:all: $(EXECUTABLE)
(6) Now add a command to the "clean:" target, either: rm -f *.a
Or: rm -f $(LIBRARY_FILES)
(7) Note that care must be taken so that LIBOBJS1/LIBOBJS2 don't overlap with SOURCES/OBJS. That is, you have to decide which sources build the libraries and which ones are strictly for the executable. I think you'll be fine on this, but I didn't see anything that spelled which .c/.o files you wanted to build your library from.
(8) All the build rules should probably be moved down the file after all the symbol definitions

Makefile C subdirectory rule to make obj

I am running a simple Makefile with no problems:
CC=gcc
CFLAGS= -std=c99 -ggdb -Wall -I.
DEPS = hellomake.h
OBJ = hellomake.o hellofunc.o
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
hellomake: $(OBJ)
gcc -o $# $^ $(CFLAGS)
The files are in the main project's directory:
./project/Makefile
./project/hellomake.c
./project/hellomake.h
Then I tried to organized the files, and put things like:
./project/Makefile
./project/src/hellomake.c
./project/include/hellomake.h
and extra subdirectories directories:
./project/lib
./project/obj
Then the new version of the Makefile:
IDIR =include
CC=gcc
CFLAGS= -std=c99 -ggdb -Wall -I$(IDIR)
ODIR=obj
LDIR =lib
LIBS=-lm
_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = hellomake.o hellofunc.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
hellomake: $(OBJ)
gcc -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
I am compiling on Linux using Emacs with the gcc compiler:
$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Then, I run on Emacs:
<Esc>
x
compile
make
And it gives the message:
"./project/src/" -*-
make: *** No rule to make target `obj/hellomake.o', needed by `hellomake'. Stop.
Compilation exited abnormally with code 2 at Wed Oct 3 17:10:01
What rule should be missing to be included in the Makefile file?
All comments and suggestions are highly appreciated.
Thanks for your suggestion, it is added to the code. Then the compiler complains:
make -k
make: *** No rule to make target `src/hellomake.c', needed by `obj/hellomake.o'.
make: *** No rule to make target `../include/hellomake.h', needed by `obj/hellomake.o'.
make: Target `obj/hellomake.o' not remade because of errors
Some other suggestion?
Thanks in advance!
To fix the error make: *** No rule to make target 'obj/hellomake.o', needed by 'hellomake'. Stop.
Change this line:
$(ODIR)/%.o: %.c $(DEPS)
To:
$(OBJ): $(ODIR)/%.o: src/%.c $(DEPS)
This creates a rule for all objects in the $(OBJ) variable. The second parameter ('$(ODIR)/%.o') extracts the file name from the full path in order to pass just the file name to the third parameter ('src/%.c').
Ok. Now I am trying another example found here [ How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories? ] and here it goes:
TARGET = hi.sh
CC = gcc
# compiling flags here
CFLAGS = -std=c99 -ggdb -Wall -I./src
TARGET = bin/hi.sh
LINKER = gcc -o
# linking flags here
LFLAGS = -Wall -I. -lm
# change these to set the proper directories where each files shoould be
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SOURCES := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS)
#$(LINKER) $(TARGETPATH)/$(TARGET) $(LFLAGS) $(OBJECTS)
#echo "Linking complete!"
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
#echo "Compiled "$<" successfully!"
.PHONEY: clean
clean:
#$(rm) $(OBJECTS)
#echo "Cleanup complete!"
.PHONEY: remove
remove: clean
#$(rm) $(BINDIR)/$(TARGET)
#echo "Executable removed!"
The files are organized as:
./project/bin/ executable
./project/ojb/*.0
./project/src/*.c and *.h
./project/Makefile
The compiler persists giving only one complaint:
make -k
/usr/bin/ld: cannot open output file /bin/hi.sh: Permission denied
collect2: ld returned 1 exit status
make: *** [bin/bin/hi.sh] Error 1
Thanks a lot for all comments and suggestions!
I think you should change this line
$(ODIR)/%.o: %.c $(DEPS)
change to
$(ODIR)/%.o : %.c $(DEPS)
add a Space after %.o.

Resources