Make error when trying to create *.o - c

I'm at my wits end here because of this extremely stupid error I'm getting from my makefile.
I finally gave up stripped the makefile down to just two lines:
%.o: %.c
gcc -c -o $# $< -I../inc
Command: make . The output:
make: *** No targets. Stop.
The spaces at the beginning are real tabs instead of spaces. The c files are in the same directory. If instead of %.o I give, say, file1.o and file1.c instead of %.c, all is well (file1.o gets created). I see plenty of examples on the 'net that use the % operator, though. If I include a clean: target, it is promptly found, like so:
%.o: %.c
gcc -c -o $# $< -I../inc
clean:
echo "this is clean!"
Command: make . The output:
echo "this is clean!"
this is clean!
Please help me out here as I'm totally clueless about what's wrong with my targets. In the second sample (the one with clean target), I guess the clean target is found and acted upon as the first one is 'invalid' somehow.

Looks like you forgot to write a target. You have just written rules of how to compile, but not what to do with those objects. I mean, I miss something like:
my_executable_file: *.o
gcc -o my_executable_file *.o
EDIT:
What is set before is true, you need a target. But as you want only to compile, your target should be something like:
OBJECTS = file.o #and whatever objects you need, as a list separated by commas
And then your target:
my_objects: $(OBJECTS)
So putting it all together:
OBJECTS = file.o #and whatever objects you need, as a list separated by commas
my_objects: $(OBJECTS)
%.o: %.c
gcc -c -o $# $< -I../inc

Below is the Makefile that will enable to any number of targets to compile
OBJ := file.o
all: $(OBJ)
%.o: %.c
gcc -c -o $# $< -I../inc
clean:
echo "this is clean!"
Here, OBJ will be the list of the files that you want to compile , like here it is file.c
Add the file name you want to compile to OBJ, when make is called it will build the target all first which depends on the OBJ.
To build OBJ the gcc command is used.

When an explicit target is not given to make, then the first (non-pattern?) target in the Makefile is used. In the case above, it is the clean target.

I see your intention to make only .o files (can be needed for creation of libraries).
You can modify your Makefile to build only .o files or build only executable by using the same Makefile
For the below directory structure (using tree command)
# tree .
.
|-- include
| `-- head.h
|-- Makefile
|-- obj
`-- src
`-- main.c
Makefile
# GNU Makefile #
# Some Variables #
CC := gcc
RM := rm
MV := mv
# Phony Targets #
.PHONY: clean
.PHONY: move
# Path for Source, Object and Include #
SRC_PATH := ./src/
OBJ_PATH := ./obj/
INCLUDE_PATH := ./include/
# Source and Object File Names #
SRC := $(SRC_PATH)main.c
OBJ := $(SRC:c=o) # Substitutes all SRC but with .c as .o (main.c becomes main.o) #
# Executable Name #
TARGET := exe
# Building Binary - use 'make' #
binary: $(TARGET) move
$(TARGET): $(OBJ)
$(CC) -o $(TARGET) $^
# Building only Object Files - use 'make object_only' #
object_only : $(OBJ) move
$(OBJ): $(SRC)
$(CC) -c -o $# $< -I $(INCLUDE_PATH)
# This rule is for moving .o files to ./obj directory (More Organised) #
move:
$(MV) $(SRC_PATH)*.o $(OBJ_PATH)
# For Cleaning - use 'make clean' #
clean:
echo "Cleaning Up!"
$(RM) -rfv $(TARGET) $(OBJ_PATH)*.o $(SRC_PATH)*.o # Delete .o and executable #
Execution:
To build only object files use
$ make object_only
To build object files and executable, use
$ make

Related

Makefile that handles subdirectories and puts object files in a object folder tree

I have a question about Makefiles with subdirectories:
I have a program with the structure
---src
|
|-> main.c
|-> morestuff.c
|-> [...]
|-> builtins -> builtin.c
-> builtin2.c
---obj
---inc
Now what I want to do is: I want to run make such that I create object files in my object directory (order structure not necessarily needed) and that I (obviously) create an executable.
I am able to do that without the subdirectories, but my pattern rules break, once I try to include the subdirectories...
My current approach (without subdirectories) looks something like this:
NAME = minishell
SRC_DIR = src/
OBJ_DIR = obj/
INC_DIR = inc/
LIBFT_DIR = libft/
LIBFT_EXEC = libft.a
CC = gcc
CFLAGS = -Wall -Werror -Wextra -g
# place all source files here
SRC = $(SRC_DIR)main.c \
$(SRC_DIR)builtin1.c \
$(SRC_DIR)builtin2.c \
[...]
# takes all named source files and converts them to .o files in the /obj directory
OBJ = $(SRC:$(SRC_DIR)%.c=$(OBJ_DIR)%.o)
# prevents rules from being considered as files
.PHONY: all clean fclean re
all: $(NAME)
# creates subdirectory /obj
$(OBJ_DIR):
#mkdir $#
#echo "Creating object directory..."
# makes sure to make a /obj dir before compiling .o files
$(OBJ): | $(OBJ_DIR)
$(OBJ): $(OBJ_DIR)%.o: $(SRC_DIR)%.c
$(CC) $(CFLAGS) -c $< -o $#
# compiles all object files and builds executable file 'minishell' -> ADJUST READLINE FOR LINUX!
$(NAME): $(OBJ)
#echo "Compiling libft..."
$(MAKE) -C libft
#echo "Compiling $(NAME)..."
$(CC) $(CFLAGS) $^ $(LIBFT_DIR)$(LIBFT_EXEC) -L $(HOME)/goinfre/.brew/opt/readline/lib/ -lreadline -o $#
#echo "SUCCESSFULLY CREATED MINISHELL!"
So how can I scale that up to handle subdirectories?
I know I could make Makefiles in subdirectories, but this is not worth the effort since there aren't a lot of files in there...
Instead of just creating the object directory before compiling, you should create the object file directory tree prior to compiling each file:
$(OBJ_DIR)%.o: $(SRC_DIR)%.c
#mkdir -p $(dir $#)
$(CC) $(CFLAGS) -c $< -o $#
$(dir $#) is a GNU make extension. You can use #mkdir -p `dirname $#` for portability to other make flavors.

Compiling all C files and creating executable with Makefile

I have a C project, which has the following file structure:
Makefile
src
|-utils
| |--vic.c
| |--vic.h
|-mod
| |--type.c
| |--type.h
|-bb.c
|-bb.h
|-main.c
So, at the root directory I have the actual Makefile and the src directory, which includes the source files. Inside the src directory there are multiple .c and .h files along with the main.c file, and there are other directories which also contain other .c and .h files. Please note that the above shown file structure is kept short for brevity. I want to create a Makefile that will automatically compile everything and generate an executable main program, and also delete the object files generated during the compilation. Currently, I have something like this:
CC=gcc
CFLAGS=
RM=rm -rf
OUT=main
SRC=src
OBJ=obj
SOURCES=$(wildcard $(SRC)/*.c)
OBJECTS=$(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SOURCES))
all: build
build: $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $#
$(RM) $(OBJ)
$(OBJ)/%.o: $(SRC)/%.c
$(CC) $(CFLAGS) -I$(SRC) -c $< -o $#
debug: CFLAGS+=-DDEBUG
debug: build
.PHONY: clean
clean:
$(RM) $(OBJ) $(OUT)
But that doesn't seem to work as expected, as when I issue make command, it returns the following error message:
Assembler messages: Fatal error: can't create obj/main.o: No such file
or directory
Any ideas how to achieve what I want?
It seems you rm -rf obj/ after each step, but there's no mkdir -p obj/ to replace it.
Since GNU make will, itself, remove intermediate targets, I don't see why you would do $(RM) $(OBJ), but your %.o target could have a line like
mkdir -p "$(shell dirname "$#")"
… to ensure that the destination directory exists.
PS: your output is named build rather than main because that's the name you gave it …

Make C and ASM files in the same makefile fails

I have written a Makefile to generate a kernel image from both ASM and C sources however it fails to compile the C sources. I think the error is in using two object lists one for ASM and one for C. If there are other issues with the file please feel free to tell me.
Terminal Output
arm-none-eabi-as -I source/ source/maths.s -o build/maths.o
arm-none-eabi-as -I source/ source/tags.s -o build/tags.o
make: *** No rule to make target 'build/firstCFile.o', needed by 'build/output.elf'. Stop.
Makefile
# The toolchain to use. arm-none-eabi works, but there does exist
# arm-bcm2708-linux-gnueabi.
ARMGNU ?= arm-none-eabi
# The intermediate directory for compiled object files.
BUILD = build/
# The directory in which source files are stored.
SOURCE = source/
# The name of the output file to generate.
TARGET = bin/kernel.img
# The name of the assembler listing file to generate.
LIST = bin/kernel.list
# The name of the map file to generate.
MAP = bin/kernel.map
# The name of the linker script to use.
LINKER = kernel.ld
# The names of libraries to use.
LIBRARIES := csud
# The names of all object files that must be generated. Deduced from the
# assembly code files in source.
OBJECTS := $(patsubst $(SOURCE)%.s,$(BUILD)%.o,$(wildcard $(SOURCE)*.s))
OBJECTS2 := $(patsubst $(SOURCE)%.c,$(BUILD)%.o,$(wildcard $(SOURCE)*.c))
# Rule to make everything.
all: $(TARGET) $(LIST)
# Rule to remake everything. Does not include clean.
rebuild: all
# Rule to make the listing file.
$(LIST) : $(BUILD)output.elf
$(ARMGNU)-objdump -d $(BUILD)output.elf > $(LIST)
# Rule to make the image file.
$(TARGET) : $(BUILD)output.elf
$(ARMGNU)-objcopy $(BUILD)output.elf -O binary $(TARGET)
# Rule to make the elf file.
$(BUILD)output.elf : $(OBJECTS) $(OBJECTS2) $(LINKER)
$(ARMGNU)-ld --no-undefined $(OBJECTS) $(OBJECTS2) -L. $(patsubst %,-l %,$(LIBRARIES)) -Map $(MAP) -o $(BUILD)output.elf -T $(LINKER)
# Rule to make the object files.
$(BUILD)%.o: $(SOURCE)%.s
$(ARMGNU)-as -I $(SOURCE) $< -o $#
$(BUILD):
mkdir $#
I think you need a rule to make from the c source:
$(BUILD)%.o : $(SOURCE)%.c
$(ARMGNU)-gcc -c -I $(SOURCE) $< -o $#

Make implicit rules with GCC: Redirecting *.o

I am trying to get make to do the following with an implicit rule:
obj/lsabase.o : inc/lsabase.h lsabase.c
cc -c lsabase.c && mv lsabase.o obj
I searched for ways to redirect the output of "cc -c .." with compiler options, but didn't find any here.
Also the implicit rule defined for compiling from source to object only lets you use $(CPPFLAGS) and $(CFLAGS).
Does anybody know how to trick make into using this (mv lsabase.o obj) in an implicit rule, so I can put all *.o files in a seperate directory?
obj/lsabase.o : inc/lsabase.h lsabase.c
cc -I"inc" -c lsabase.c -o obj/lsabase.o
I would
avoid doing the mv manually but rather telling gcc to put in the obj dir
let gcc handle the dependencies (by creating .d files)
and here is what I usually do when all my .c files are in a subdir and I want to compile all of them in a parallel dir obj (that I can easily remove):
default: my_code
#add subdirs
DIRS := $(shell find src -type d)
#add include directives for subdirs
CFLAGS += $(DIRS:%=-I%)
#collect all c files
SRCS := $(shell find src/* -name \*.c)
OBJS := $(addprefix obj/, $(SRCS:.c=.o))
DEPS := $(addprefix obj/, $(SRCS:.c=.d))
# this generates a dependency file for every .c
obj/%.d: %.c
# mkdir -p "$(#D)"
# echo "Checking dependencies for $<"
# create and modify dependecy file .d to take into account the location obj (sed magical)
# gcc $(CFLAGS) -MM $< 2>/dev/null | sed -e "s#\(^.*\)\.o:#obj/$(shell dirname $<)/\1.d obj/$(shell dirname $<)/\1.o:#" > $#
#this compiles
obj/%.o : %.c
gcc $(CFLAGS) -c $< -o $#
#this creates the executable
my_code: $(OBJS)
gcc $(OBJS) -o $# $(LDFLAGS)
# this does the magic
-include $(DEPS)
clean:
rm -rf obj
If you're new to Make, this might seem difficult, but it's really powerful once you get through.
you can write the makefile rule this way:
obj/lsabase.o : lsabase.c inc/lsabase.h
<tab>cc $(CFLAGS) -c $< -o $# -Iinc/.
where, in the actual makefile, the <tab> would be replaced with an actual tab character
Notice the *.c file is first in the list of dependencies, so can use the $< shortcut
You mentioned wanting to do this for all the object files..
obj/$.o : %.c inc/%.h
<tab>cc $(CFLAGS) -c $< -o $# -Iinc/.
However, that may not be the most flexible. For maximum flexibility, suggest adding a rule to generate and include dependency files named *.d. Then using:
obj/$.o : %.c %.d
<tab>cc $(CFLAGS) -c $< -o $# -Iinc/.

How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?

A few months ago, I came up with the following generic Makefile for school assignments:
# ------------------------------------------------
# Generic Makefile
#
# Author: yanick.rochon#gmail.com
# Date : 2010-11-05
#
# Changelog :
# 0.01 - first version
# ------------------------------------------------
# project name (generate executable with this name)
TARGET = projectname
CC = gcc -std=c99 -c
# compiling flags here
CFLAGS = -Wall -I.
LINKER = gcc -o
# linking flags here
LFLAGS = -Wall
SOURCES := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS := $(SOURCES:.c=*.o)
rm = rm -f
$(TARGET): obj
#$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
#echo "Linking complete!"
obj: $(SOURCES) $(INCLUDES)
#$(CC) $(CFLAGS) $(SOURCES)
#echo "Compilation complete!"
clean:
#$(rm) $(TARGET) $(OBJECTS)
#echo "Cleanup complete!"
This will basically compile every .c and .h file to generate .o files and the executable projectname all in the same folder.
Now, I'd like to push this a little. How can I write a Makefile to compile a C project with the following directory structure?
./
./Makefile
./src/*.c;*.h
./obj/*.o
./bin/<executable>
In other words, I'd like to have a Makefile that compiles C sources from ./src/ into ./obj/ and then link everything to create the executable in ./bin/.
I've tried to read different Makefiles, but I simply can't make them work for the project structure above; instead, the project fails to compile with all sorts of errors. Sure, I could use full blown IDE (Monodevelop, Anjuta, etc.), but I honestly prefer to stick with gEdit and the good ol' terminal.
Is there a guru who can give me a working solution, or clear information about how this can be done? Thank you!
** UPDATE (v4) **
The final solution :
# ------------------------------------------------
# Generic Makefile
#
# Author: yanick.rochon#gmail.com
# Date : 2011-08-10
#
# Changelog :
# 2010-11-05 - first version
# 2011-08-10 - added structure : sources, objects, binaries
# thanks to http://stackoverflow.com/users/128940/beta
# 2017-04-24 - changed order of linker params
# ------------------------------------------------
# project name (generate executable with this name)
TARGET = projectname
CC = gcc
# compiling flags here
CFLAGS = -std=c99 -Wall -I.
LINKER = gcc
# linking flags here
LFLAGS = -Wall -I. -lm
# change these to proper directories where each file should 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) $(OBJECTS) $(LFLAGS) -o $#
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o $#
#echo "Compiled "$<" successfully!"
.PHONY: clean
clean:
#$(rm) $(OBJECTS)
#echo "Cleanup complete!"
.PHONY: remove
remove: clean
#$(rm) $(BINDIR)/$(TARGET)
#echo "Executable removed!"
First, your $(OBJECTS) rule is problematic, because:
it's kind of indiscriminate, making all sources prerequisites of every object,
it often uses the wrong source (as you discovered with file1.o and file2.o)
it tries to build executables instead of stopping at objects, and
the name of the target (foo.o) is not what the rule will actually produce (obj/foo.o).
I suggest the following:
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
#echo "Compiled "$<" successfully!"
The $(TARGET) rule has the same problem that the target name does not actually describe what the rule builds. For that reason, if you type make several times, Make will rebuild the target each time, even though there is no reason to. A small change fixes that:
$(BINDIR)/$(TARGET): $(OBJECTS)
$(LINKER) $# $(LFLAGS) $(OBJECTS)
#echo "Linking complete!"
Once that's all in order, you might consider more sophisticated dependency handling; if you modify one of the header files, this makefile will not know which objects/executables must be rebuilt. But that can wait for another day.
EDIT:
Sorry, I omitted part of the $(OBJECTS) rule above; I've corrected it. (I wish I could use "strike" inside a code sample.)
You can add the -I flag to the compiler flags (CFLAGS) to indicate where the compiler should look for source files , and the -o flag to indicate where the binary should be left:
CFLAGS = -Wall -I./src
TARGETPATH = ./bin
$(TARGET): obj
#$(LINKER) $(TARGETPATH)/$(TARGET) $(LFLAGS) $(OBJECTS)
#echo "Linking complete!"
In order to drop the object files into the obj directory, use the -o option when compiling. Also, look at the $# and $< automatic variables.
For example, consider this simple Makefile
CFLAGS= -g -Wall -O3
OBJDIR= ./obj
SRCS=$(wildcard *.c)
OBJS=$(SRCS:.c=.o )
all:$(OBJS)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $(OBJDIR)/$#
Update>
By looking at your makefile, I realize you are using the -o flag. Good. Continue using it, but add a target directory variable to indicate where the output file should be written.
I have stopped writing makefiles these days, if your intention is to learn go ahead, else you have good makefile generator that comes with eclipse CDT. If you want some maintainability / multiple project support with in your build tree, have a look at the following -
https://github.com/dmoulding/boilermake I found this pretty good..!

Resources