CC := cc
NAME := minishell
SRCS = ./Srcs/xsh.c
DIR = .build
OBJS := $(SRCS:%.c=$(DIR)%.o)
OBJS := $(addprefix $(DIR), $(OBJS))
$(DIR)/%.o : %.c
$(CC) -c -o $# $<
$(NAME) : $(OBJS) | $(DIR)
$(CC) -o $# $^
$(DIR):
mkdir -p $(#)
all : $(NAME)
I am trying to store all .o files in the build directory
Makefile:12: warning: overriding commands for target .build
Makefile:8: warning: ignoring old commands for target .build
make: *** No rule to make target %.c, needed by .build. Stop
Your line numbers are off by one which makes these errors hard to understand. Please be sure to include the exact makefile and errors so that they match up.
However, I assume that line #8 is:
$(DIR)/%.o : %.c
and line #12 is:
$(DIR):
The only way that this could give that error is if your DIR variable ended in spaces:
DIR = .build
^-space here
Makefiles preserve ending spaces on variables so be sure you don't do that.
Note if you had a newer version of GNU make it would warn about this:
Makefile:8: *** mixed implicit and normal rules: deprecated syntax
I guess that's still not super-helpful but it's something! :)
Related
Automate the compilation of auto-generated C files with regular C files
We have developed a program "cperformer" that is able to generate a C file from a text file (to keep it simple).
It is a kind of "meta-compiler" that generates C file as output. Thus, we would like to improve the usage of this "C generator" by automating the generation of each C file as a first step of a makefile, and then compile and link together all of these generated C files with other C files already present with GCC in the same makefile.
Makefile 1
C_GEN :=./cperformer -n
CC :=gcc
CFLAGS :=-I.
#List all .c files generated from .text files
AUTO_SRCS = $(wildcard *.text)
AUTO_OBJS_C := $(patsubst %.text,%_alg.c,$(AUTO_SRCS))
$(info *INFO* Text files = $(AUTO_SRCS))
#List all .c files to compile (auto-generated or not)
SRCS = $(AUTO_OBJS_C)
SRCS += $(wildcard *.c)
OBJS := $(patsubst %.c,%.o,$(SRCS))
$(info *INFO* C files = $(SRCS))
# Main target rule
target : $(OBJS)
$(CC) -o $# $(OBJS) $(CFLAGS)
# Pre-compilation step (some C files generation)
prelim $(AUTO_OBJS_C): $(AUTO_SRCS)
$(C_GEN) $<
# Pre-compilation step (object files generation)
%.o: %.c
$(CC) -c -o $# $< $(CFLAGS)
all: prelim target
clean :
rm -f TARGET $(OBJS) *_alg*
Error 1
$ make all
*INFO* Text files = file3.text file2.text file1.text
*INFO* C files = file3_alg.c file2_alg.c file1_alg.c linked_list.c main.c
./cperformer -n file3.text
Compiling: file3.text ...
No error.
Done.
gcc -c -o file3_alg.o file3_alg.c -I.
./cperformer -n file3.text
Compiling: file3.text ...
No error.
Done.
gcc -c -o file2_alg.o file2_alg.c -I.
gcc: error: file2_alg.c: No such file or directory
gcc: fatal error: no input files
compilation terminated.
make: *** [Makefile:29: file2_alg.o] Error 1
It fails because the "cperformer" program is asked to generate the same C file each time "file3.c" so GCC don't find "file2.c" as expected and it aborts the compilation.
Makefile 2
Replace the C generative rule of the above makefile with the use of "%" :
# Pre-compilation step (some C files generation)
%.c: %.text
$(C_GEN) $<
Error 2
make: *** No rule to make target 'file3_alg.o', needed by 'target'. Stop.
Nothing compiles here.
Makefile 3
The dirty fix
batch_c_generation :
#$(foreach TXT_FILE, $(AUTO_SRCS), $(C_GEN) $(TXT_FILE);)
This is kind of working but remains very dirty because it re-generates all C files at each build and some duplication errors appear when it is not properly cleared between each make.
How can I fix the makefile ?
You were close -- simply fix your pattern rule to look like this:
%_alg.c : %.text
$(C_GEN) $<
As #tripleee mentioned, the reason your makefile1 rule failed was that it expands to something like:
file2_alg.c file1_alg.c: file2.text file1.text
$(CGEN) $<
In this case $< expands to the first dependency which will always be file2.text...
In your makefile2 example, you used %.c instead of %_alg.c (and hence there's no rule to build file2_alg.c, and therefore no rule to build file2_alg.o)
I am trying to create a makefile for a new project. the project contains so far just some basic main func and some funcs declarations.
my makefile makes objects from source files, but no executable is compiled. exit with error:
mkdir -p build/./src/app/
gcc -std=gnu99 -Wall -I./src -I./src/app -I./src/include -I./src/lib -c src/app/main.c -o build/./src/app/main.o
mkdir -p build/./src/app/
gcc -std=gnu99 -Wall -I./src -I./src/app -I./src/include -I./src/lib -c src/app/Emsg.c -o build/./src/app/Emsg.o
gcc -std=gnu99 -Wall -I./src -I./src/app -I./src/include -I./src/lib -o bin/Main
gcc: fatal error: no input files
compilation terminated.
Makefile:59: recipe for target 'all' failed
make: *** [all] Error 1
this is my make file:
CFLAGS := -std=gnu99 -Wall
ifeq ($(STRIP), yes)
CFLAGS := $(CFLAGS) -s
endif
BUILD_DIR := ./build
BIN_DIR := ./bin
SRC_DIRS := ./
SRC_APPS := ./src
SRC_TESTS := ./test
SRCS_APPS := $(shell find $(SRC_APPS) -name '*.c')
SRCS_TESTS := $(shell find $(SRC_TESTS) -name '*.c')
OBJS_APPS := $(SRCS_APPS:%.c=$(BUILD_DIR)/%.o)
OBJS_TESTS := $(SRCS_TESTS:%.c=$(BUILD_DIR)/%.o)
OBJS_ALL := $(OBJS_APPS)
OBJS_ALL_TESTS := $(OBJS_ALL) $(OBJS_TESTS)
INC_APPS_DIRS := $(shell find ./src -type d)
INC_INCLUDES := src/include
INC_TESTS_DIRS := test/
INC_APPS_FLAGS := $(addprefix -I,$(INC_APPS_DIRS))
INCLUDE_ALL := $(INC_APPS_FLAGS)
CC := gcc
ifeq ($(TEST), yes)
CFLAGS := $(CFLAGS) -D TEST
OBJECTS := $(OBJS_APPS) $(OBJS_TESTS)
INCLUDE := $(INC_TESTS_LIBS_FLAGS) $(INC_TESTS_FLAGS)
DEPEND_LST := apps tests
COMP_ARGS := $(CC) $(CFLAGS) $(INCLUDE) $(OBJECTS) -L$(INC_TEST_LIBS) -o bin/Test
else
DEPEND_LST := apps
COMP_ARGS := $(CC) $(CFLAGS) $(INCLUDE_ALL) $(OBJECTS) -o bin/Main
endif
# All
all: $(DEPEND_LST)
$(COMP_ARGS)
#Tests
tests: $(OBJS_TESTS)
$(BUILD_DIR)/%.o: %.c
$(MKDIR_P) $(dir $#)
$(CC) $(CFLAGS) $(INCLUDE_ALL) -c $< -o $#
# Apps
apps: $(OBJS_APPS)
$(BUILD_DIR)/%.o: %.c
$(MKDIR_P) $(dir $#)
$(CC) $(CFLAGS) $(INCLUDE_ALL) -c $< -o $#
# Clean
clean:
$(RM) -r $(BUILD_DIR)
# not sure what these two lines do..
-include $(DEPS)
MKDIR_P ?= mkdir -p
I'm simply running make.
files hierarchy is:
src dir
app dir (contains main.c and more files)
include dir (contains some .h files)
lib dir (empty)
test dir (contains another main.c file)
Makefile file
Install GNU remake and run remake -X.
It will put you into a debugger and then you can run step to see step by step what the makefile is doing. Here is that applied to your Makefile:
$ remake -X
Reading makefiles...
Updating makefiles...
Updating goal targets...
-> (/tmp/so/Makefile:45)
all: apps
remake<0> step
File 'all' does not exist.
File 'apps' does not exist.
Must remake target 'apps'.
Successfully remade target file 'apps'.
<- (/tmp/so/Makefile:56)
apps
remake<1> where
=>#0 apps at Makefile:56
#1 all at Makefile:45
remake<3> x OBJS_APPS
Makefile:17 (origin: makefile) OBJS_APPS := ...
See the link for videos. Or https://github.com/rocky/remake for some screen shots
Make's output presents the commands it runs. For a serial build, at least, this unambiguously communicates what command produced each diagnostic message emitted. In your case, the command that caused the error immediately preceeds it in the output:
gcc -std=gnu99 -Wall -I./src -I./src/app -I./src/include -I./src/lib -o bin/Main
So what's wrong with that? Why, exactly what the diagnostic says: it doesn't specify any input files to operate upon. No C source files to compile, no object files or libraries to link. Nothing from which to build the designated output file.
Supposing that you've presented a complete makefile that produces the problem for you, that command must come from an attempt to build target all via this rule:
all: $(DEPEND_LST)
$(COMP_ARGS)
That's a bit suspicious on its face, because an all target typically provides only a prerequisite list, not a recipe. Each prerequisite that may need to be built would then have its own rule. But it's not inherently wrong to provide a recipe, and we need to consider the recipe itself to determine the nature of your problem. In this case, we have suspicious point #2: the recipe is specified entirely via a single variable. But I already knew that, because I had to trace through that to identify this rule as the source of the error in the first place.
In particular, the only place where the text bin/Main appears in the makefile is in this else block:
else
DEPEND_LST := apps
COMP_ARGS := $(CC) $(CFLAGS) $(INCLUDE_ALL) $(OBJECTS) -o bin/Main
endif
That indeed provides the command line variable referenced by the all target (and by nothing else), and it matches up cleanly with the command that causes the error. And what do we find when we match the bits of the command line to the variables from which that version of COMP_ARGS is built? We find that all the bits are covered by variables other than OBJECTS, which evidently expands to nothing (you can even see the separate leading and trailing space characters around its empty value). And why does OBJECTS expand to an empty value? Because it is never set when that branch of the conditional is exercised.
Personally, I would be inclined to rewrite the whole makefile to be more idiomatic and to rely less on GNU make extensions, but the simplest way forward would probably be to put an appropriate definition of the OBJECTS variable in the else block I pointed out.
So I wrote a program to calculate Caesar cipher but I think it's not really matter - what matter is that when I'm trying to do make the compiler or who checks the syntax of my makefile is throw an error says :
make: *** No rule to make target 'clean.', needed by 'PHONY'. Stop.
In my directory I have 5 files:
main.c
ceasar.c
ceasar.h
parser.c
parser.h
and the makefile looks like:
PHONY : all clean.
CFLAGS = -c -g -Wall
CXXFLAGS = -o
CC = gcc
OBJECTS = main.o ceasar.o parser.o
EXTRA_SRCS = ceasear.h parser.h
all : ex1
ex1 : $(objects)
$(CC) $(CXXFLAGS) ex1 $(objects)
%.o : %.c $(wildcard $(EXTRA_SRCS))
$(CC) $(CFLAGS) $<
clean:
rm *.o
The makefile should clean the objects files when typed make clean
and the line $(wildcard $(EXTRA_SRCS)) should checks if the c file has header file(parser and caeser, not main).
I'm using ubuntu 15.10 and please help me :)
It's possible to specify fictitious target that has as purpose to execute a sequence of operations. These targets do not specify any dependency and must not appear as the first rule, to be carried out only if they are passed as arguments to make command explicitly. Fictitious target is not a file (the file does not exist) it is used to initiate the execution of the command in each case.
CFLAGS = -c -g -Wall
CXXFLAGS = -o
CC = gcc
OBJECTS = main.o ceasar.o parser.o
EXTRA_SRCS = ceasear.h parser.h
all : ex1
ex1 : $(objects)
$(CC) $(CXXFLAGS) ex1 $(objects)
%.o : %.c $(wildcard $(EXTRA_SRCS))
$(CC) $(CFLAGS) $<
.PHONY: clean
clean: rm *.o
Be careful because the fictitious target may be masked by existing files: if accidentally in the directory it creates a file called the same name of the fictitious target then, as the target has no dependencies, and the file already exists, that file does not need to be updated and then the command list will never be executed.
I'm new to Stack Overflow. I'm currently having a hard time solving a simple problem.
In my shell/ directory, I have:
CVS/
include/
Makefile
obj
src
My problem occurs when trying to direct object files to be built in obj, but when I run make with the following code:
# Beginning of Makefile
OBJS = obj/shutil.o obj/parser.o obj/sshell.o
HEADER_FILES = include/shell.h include/parser.h
EXECUTABLE = simpleshell
CFLAGS = -Wall
CC = gcc
# End of configuration options
#What needs to be built to make all files and dependencies
all: $(EXECUTABLE)
#Create the main executable
$(EXECUTABLE): $(OBJS)
$(CC) -o $(EXECUTABLE) $(OBJS)
#Recursively build object files
%.o: %.c
$(CC) $(CFLAGS) -c -o $# $<
#Define dependencies for objects based on header files
#We are overly conservative here, parser.o should depend on parser.h only
$(OBJS) : $(HEADER_FILES)
clean:
-rm -f $(EXECUTABLE) obj/*.o
run: $(EXECUTABLE)
./$(EXECUTABLE)
tarball:
-rm -f $(EXECUTABLE) obj/*.o
(cd .. ; tar czf Kevin_Fairchild_a3.tar.z shell )
# End of Makefile
I get this error:
gcc -o simpleshell obj/shutil.o obj/parser.o obj/sshell.o
gcc: obj/shutil.o: No such file or directory
gcc: obj/parser.o: No such file or directory
gcc: obj/sshell.o: No such file or directory
gcc: no input files
make: *** [simpleshell] Error 1
What simple piece am I missing? I will continue to research and learn more about Makefiles
The trouble is that the pattern rule
%.o: %.c
...
doesn't actually match what you're trying to do. The source file is actually src/shutil.c, so this rule doesn't fit. All Make sees is this rule:
$(OBJS) : $(HEADER_FILES)
There are no commands, so Make concludes that no action is necessary. It then proceeds with the rule for simpleshell, which fails because the objects aren't there.
Try this:
obj/%.o: src/%.c
$(CC) $(CFLAGS) -c -o $# $<
There are more sophisticated variations, once this much is working.
after adding that simple modification, which I originally attempted before posting here, i.e.
obj/%.o: src/%.c
I recieved this error, so originally I though it was something else.
gcc -Wall -c -o obj/shutil.o
src/shutil.c
src/shutil.c:14:19: error: shell.h: No such file or directory
src/shutil.c: In function ‘signal_c_init’:
src/shutil.c:72: error: ‘waitchildren’ undeclared (first use in this function)
src/shutil.c:72: error: (Each undeclared identifier is reported only once
src/shutil.c:72: error: for each function it appears in.)
src/shutil.c: In function ‘checkbackground’:
src/shutil.c:90: warning: implicit declaration of function ‘striptrailingchar’
src/shutil.c: At top level:
src/shutil.c:101: warning: conflicting types for ‘striptrailingchar’
src/shutil.c:90: note: previous implicit declaration of ‘striptrailingchar’ was here
make: *** [obj/shutil.o] Error 1`
Thanks for the quick reply by the way!
I am in the process of porting some code that was developed in the codeblocks IDE. I am transferring it to a Linux server where I can only use the command line to compile the code. The code is quite large (maybe 100 files) and I need to update the include commands in many files. For when I try to compile it errors on for instance: #include <gsl/gsl_math.h> with a file cannot be found error. I am assuming it cannot be found because the location of the gsl folder was declared in one of the search directory field options in the IDE. I could go through each file an update to the correct path, but is there a better way of doing this for use with a makefile?
Thanks!
EDIT Makefile In Question
# -c : do not link, just create object file
# -o : output file name
CFLAGS += -c -O2 -I../ctraj -I../cspice/include -I../SGP4 -I../cconj -I../GSL-1.13/include
LIBS = -L../ctraj -lctraj -L../cspice/lib -lcspice -L../SGP4 -lsgp4 -L../cconj -lcconj -L./ -lgsl-0 -lgslcblas-0 -lm
DEPS = light.h ../ctraj/ctraj.h ../cconj/cconj.h
OBJ = light.o tle.o propagator.o orbitfit.o conjunction.o light_displacement.o forces_LF.o
OUT = light.exe
%.o: %.c $(DEPS)
gcc -o $# $< $(CFLAGS)
light: $(OBJ)
cd ../ctraj/; make
gcc -o $(OUT) $(OBJ) $(LIBS)
clean:
rm *.o $(OUT)
Edit 2
Folder Structure
light->(GSL-1.13, Light, cconj, ctraj)
the makefile is inside the Light folder.
Error Message
cd ../ctraj/; make
make[1]: Entering directory `/light/ctraj'
gcc -o forces.o forces.c -c -Wall -Wno-maybe-uninitialized -Wno-unused-but-set-variable -O2 -I../cspice/include -Inrlmsise
In file included from ../Light/../cconj/cconj.h:12:0,
from ../Light/light.h:13,
from forces.c:3:
../Light/../cconj/../GSL-1.13/include/gsl/gsl_blas.h:26:28: fatal error: gsl/gsl_vector.h: No such file or directory
compilation terminated.
make[1]: *** [forces.o] Error 1
make[1]: Leaving directory /light/ctraj'
make: *** [light] Error 2
EDIT 3
Second makefile in cconj
# -c : do not link, just create object file
# -o : output file name
#-L../cconj -lcconj
CFLAGS += -c -O2 -I./ -I../GSL-1.13/include
LIBS = -L./ -lgsl-0 -lgslcblas-0 -lm
INC= -I../GSL-1.13/include
DEPS = cconj.h
OBJ = cconj_util.o ellipse_intersect.o collision_prob_real.o rcs2size.o
OUT = libcconj.a
%.o: %.c $(DEPS)
gcc -o $# $< $(CFLAGS)
cconj: $(OBJ)
ar rcs $(OUT) $(OBJ)
clean:
rm *.o $(OUT)
Try adding this line to your makefile, and tell us if it works:
CFLAGS += -I../GSL-1.13/include
In order to compile source code and produce object files, Make must use a rule. (If you don't put such a rule in the makefile, Make has a default rule for that purpose.) It looks something like this:
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
Without digging too deeply into how that works, we can say that CFLAGS is a list of arguments to be passed to the compiler. When we add -I../GSL-1.13/include, we tell the compiler "if you want to #include something and can't find it elsewhere, look in ../GSL-1.13/include".
If this approach doesn't work, then there's probably a rule in the makefile we must find and alter.
EDIT:
The problem isn't in this makefile (which already contains a reference to GSL-1.13/include). In this command:
cd ../ctraj/; make
this makefile launches a second Make process, which uses the Makefile in light/cconj/. According to the compiler output (gcc -o forces.o ...), that makefile does not include the reference. So try adding the same line there, and if that doesn't work, post that makefile and we'll keep looking.
Use -I option of gcc to specify where to look for includes.