The main problem is that some your recipe for linkage is missing the output file, and that your compilation is missing -c.
In case you're using GNU make, the following Makefile would be sufficient to do what you want to do:
CFLAGS:=-Wall -std=c11 CPPFLAGS:=-DNDEBUG .PHONY: all all: caltool caltool: caltool.o calutil.o .PHONY: clean clean:: $(RM) *.o
Explanation:
- When you're not using target-specific variables, you should use
:= instead of = to assign variables so that they're expanded at assignment and not at evaluation. - When your
Makefile grows and you split it, you might want to have multiple targets called clean which all would be executed. In that case use clean:: instead of clean:. - There's a predefined variable to call
rm, it is $(RM) and it includes the -f flag to prevent the Makefile from failing in case one or more of the files to be removed do not exist in the first place. - The pattern for
clean should be *.[adios] (that's really easy to remember, adios is Spanish for goodbye) so that it removes intermediate archives (.a when you build your own static libraries), dependency files (.d), preprocessor output (.i) and assembler files (.s) in case you use -save-temps to see what the compiler is doing. - GNU make has built-in rules to compile and link, see http://git.savannah.gnu.org/cgit/make.git/tree/default.c?id=3.81
- The built-in rule for compilation calls
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $< so you don't need to write your own rule. - The built-in rule for linkage calls
$(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@
- Targets which are not files themselves should be declared
.PHONY to prevent confusion when a user creates a file with the same name, like all or clean. - I do not see how any of your commands would create a file matching the glob pattern
*.out, so I removed that part of the clean rule. - Flags for the preprocessor should go into
CPPFLAGS instead of CFLAGS. Preprocessor flags typically are all those -D and -I flags and would also be passed to other tools that use a C preprocessor in the same project, like splint or PC-Lint.
When the Makefile is run, it is looking how to make all, and it finds that for all it has to make caltool. For caltool it finds that it has to first make calutil.o and caltool.o. When it tries to make calutil.o and caltool.o, it finds that it can make them from calutil.c and caltool.c and will do so. Then it will link caltool.o and calutil.o into caltool.
From your naming I guessed that it's caltool.c that contains the main() function. It is helpful to place the object which contains main() first once you use static link libraries.
Edit: Here's some more magic for you. I assume that you have a header file calutil.h which is included by caltool.c to access extern symbols provided by calutil.c. You want to rebuild all objects that depend on these header files. In this case, add the following lines to your Makefile:
CPPFLAGS+=-MMD -include caltool.d calutil.d
In order to not have the list of objects multiple times, you could add a variable objects like this:
objects:=caltool.o calutil.o
You would then build the application with this rule:
caltool: $(objects)
And include the dependency files like this:
-include $(objects:.o=.d)
In case you keep your working tree "clean", i.e. do not "pollute" it with "alien" code, i.e. you always want to include all .c files in your project, you can change the definition of objects as follows:
sources:=$(wildcard *.c) objects:=$(sources:.c=.o)
In case you wonder why it is CPPFLAGS (uppercase) but objects (lowercase): it is common to use uppercase for all variables which configure the recipes of rules and control the built-in behavior of make, tools built on top of it, and classic environment variables, and lowercase variables for everything else.
makedo you use? For what you want to achieve, yourMakefilemight be overly complicated, especially when you're using GNU make.-c, socaltool.ois a complete program not an object file.