I have a makefile I use to compile a single file. When I need to pass an argument, I use target=targetFile.
The script takes the argument, looks for the file (within the same directory) that has the same value as the argument and compiles it.
I use this for compiling problems from uhunt and uva, which use a single c++ file. So I dont' need multiple makefiles for multiple source files. Single makefile for multiple source files is the reason I made the makefile.
Here's the code I have so far
OBJS = $(target).o
CC = g++
CFLAGS = -Wall -g -std=c++11
INCLUDE = -I./$(target)
#default command to run
all : Main-$(target) clean run
#compile and build
Main-$(target) : $(OBJS)
$(CC) $(CFLAGS) $^ -o $#
%.o : %.cpp
$(CC) -c $(CFLAGS) $<
#remove object and any other garbage files.
clean:
rm -rf -d $(target).o *~ *% *# .#*
#remove the compiled file
clean-all:
$(clean) rm Main-$(target)
#run the compiled file
run:
./Main-$(target)
The command I use to compile is,
make target=sourceFile
Also I don't include the file extension, I have all my source file extensions to be cpp
What I want in the end is:
make sourceFile
Just a side note, for using the command clean and clean-all, I use
make target=sourceFile clean
make target=sourceFile clean-all
I'd prefer if I can use:
make sourceFile clean
make sourceFile clean-all
You may use common Makefile variable MAKECMDGOALS that contains all targets passed to make.
Please try this variant
CC = g++
CFLAGS = -Wall -g
MAKECMDGOALS := $(filter-out clean, $(MAKECMDGOALS))
.PHONY: $(MAKECMDGOALS)
$(MAKECMDGOALS):
$(CC) $(CFLAGS) $#.c -o Main-$#
clean:
rm -f *.o
Here the lines
$(MAKECMDGOALS):
$(CC) $(CFLAGS) $#.c -o Main-$#
will generate separate build targets for each word in MAKECMDGOALS.
Note, we need this Makefile to know that 'clean' is a target for removing stuff, but not to attempt build Main-clean. This why we remove clean from MAKECMDGOALS using filter-out function.
So if we run make a b clean, the build system will generate automatically targets for building Main-a and Main-b and then use already written clean target
Disclaimer -- this is a non-standard use of Make, and will therefore open up all kinds of corner cases, so I don't recommend it. This is better suited for a shell script calling make. That being said... it is an interesting question.
You can't do make xxx clean, and not have it try to build xxx (unless you do some really nasty cludge using recursive make, but I won't go there). You could do something like make clean-xxx though, as follows:
%:Main-%
Main-%:%.cpp
$(CC) $(CFLAGS) $< -o Main-$#
clean-%:
rm Main-$*
Notice that %-clean has a shorter stem, and therefor takes precedence over the % if the make target starts with clean-.
Related
I am trying to write a makefile in a subdirectory of my eclipse makefile project.
MyProject \
test.cpp
Build\
Makefile
I am also trying to create a generic makefile. I am having trouble defining the targets since the build is not happening in the same directory as the source.
CC = g++
CC_FLAGS = -g3
EXEC = test
SOURCEDIR = ..
SOURCES = $(shell find $(SOURCEDIR) -name '*.c' -o -name '*.cpp')
OBJECTS = $(addsuffix .o,$(subst ../,,$(SOURCES)))
.DEFAULT_GOAL = all
$(EXEC): $(OBJECTS)
$(CC) $(OBJECTS) -o $(EXEC)
%.o: %.cpp
$(CC) -c $(CC_FLAGS) $< -o $#
.PHONY: clean
clean:
rm -f $(EXEC) $(OBJECTS)
.PHONY: all
all: $(EXEC)
Right now when I build I get the error...
make all
make: *** No rule to make target 'test.cpp.o', needed by 'test'. Stop.
Can anyone tell me why this is not working or recommend a better approach.
If you change your dependency from object to source as follows:
%.cpp.o: $(SOURCEDIR)/%.cpp
it seems to work.
In general I would prefer to NOT do anything in a build dir, because I personally expect a build dir is a temporary dir which can be removed completely for distribution which is not the case if the Makefile resists there. But this is a matter of taste.
Also I do not prefer to use all c/cpp you find as objects/sources in the make process. If you need to add files for different variants in your projects, you enter a nightmare to change all these things later.
And also as a hint: Typically objects are <basename>.o and not <basename>.cpp.o
And another one:
Users expect that the clean target also remove the executable. If not, you will never see a rebuild by simply do make clean; make, because the executable is in place and all dependencies are fulfilled.
I'm writing C++ project made of few files on Linux. The project have no subdirectories.
I wanted like to have some as simple as possible, generic build script.
By generic, I mean that I don't want to hardcode file names, so that when I put new .cpp file into project, I don't have to modify build script. It should find and compile all modyfied source files in current directory, and link object files into executable. Nothing more.
I don't care about tool you'll use, since I don't know any yet.
I don't want to learn a tool from basics to write something as simple as that. For now, I just need a code, I'll learn when I'll need something more fancy.
What I tryed
make:
a.out: %.o
$(CXX) %.o
%.o: %.cpp
$(CXX) -Wall -c %.cpp
with no success:
make: *** Brak reguĊ do zrobienia obiektu `%.o', wymaganego przez `a.out'. Stop.
my translation of this message:
make: *** No rules to make object `%.o', required by `a.out'. Stop.
Before someone will ask, I'll answer: yes, my makefile is indented with 1 tab, not with spaces.
make -d prints out 664 lines, so I won't paste it here.
scons:
Program("main.cpp")
It's copyed from some StackOverflow answer, but it is definietly intended to build a executable from one source file, because I get linker errors when I want use it.
I ended us using bash:
g++ -Wall *.cpp
Simple. Does the job well... for now. I don't think it's elegant and I know it's probably inefficent, because it recompiles everything, even unmodyfied files.
I guess that you have a directory full of single-source C++ programs (e.g. each program has one single C++ source file) named .cpp (e.g. foo.cpp & bar.cpp), each independently compiled to an executable (e.g. foo & bar). You might try the following (untested) Makefile for GNU make.
CXX= g++
CXXFLAGS= -Wall -Wextra -g -O
RM= rm -vf
SOURCES= $(wildcard *.cpp)
BINARIES= $(patsubst %.cpp, %, $(SOURCES))
.PHONY: all clean
all: $(BINARIES)
clean:
$(RM) *~ *.o $(BINARIES)
Read the documentation of GNU make and try make -p to find the builtin rules. See also these two examples of Makefile-s: this & that
If on the contrary you want one single executable myprogram from all the *.cpp files (like foo.cpp & bar.cpp etc....), you still can use $(wildcard *.cpp) in your Makefile (and you'll better not name a.out your executable, but something more meaningful), something like (in addition of common stuff like CXXFLAGS= above):
SOURCES= $(wildcard *.cpp)
OBJECTS= $(patsubst %.cpp, %.o, $(SOURCES))
all: myprogram
myprogram: $(OBJECTS)
$(LINK.cc) $^ -o $# $(LIBES)
In all cases, using $(wildcard *.cpp) is enough to have a Makefile generic enough on the list of sources. You may want to generate autodependencies (using gcc -M things, to some of your header files), see this.
Notice that you might have some C++ source or header files generated by some other means (e.g. your own awk or python script, or a _timestamp.c file generated with date, or some C++ files produced by a code generator like GNU bison or gperf, etc, etc...). Then you need to add specific rules into your Makefile.
So in practice, I don't believe in fully generic build files, but I am trying to show you that a Makefile can be almost generic and short. At some time you'll adapt it to your particular needs.
SRC := $(wildcard src/*.c)
DEP := $(SRC:src/%.c=lib/%.d)
OBJ := $(SRC:src/%.c=lib/%.o)
CFLAGS := -Wall -Wextra -O2 -MMD
# Executable
lib/mines: lib/assets.o $(OBJ)
${CC} $^ -o $#
# Object files
lib/%.o:: src/%.c
${CC} -c $< -o $# ${CFLAGS}
# Dependencies
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
-include $(DEP)
.PHONY: clean
clean:
rm lib/*
I have the following Makefile in a directory full of .cpp and .h files:
CFLAGS=-g -std=c++0x -Wall -pedantic -Wextra -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS -O0
CXX=g++
LDFLAGS=-lgmp -lmathsat -lz3
all: Foo.o Bar.o
$(CXX) $(CFLAGS) -o myexe Foo.o Bar.o $(LDFLAGS)
depend: .depend
.depend: $(wildcard *.cpp)
rm -f ./.depend
$(CXX) $(CFLAGS) -MM $^ > ./.depend
include .depend
%.o: %.cpp
$(CXX) $(CFLAGS) $(INCLUDE) $< -c
clean:
rm -f *.o myexe
When I hit make, it invariably executes the last step (linking) even when none of the .o files have changed. How can I prevent make from doing that? I'd expect make to output Everything up-to-date or something similar.
I'm on a i686 GNU/Linux machine with GNU Make 3.82 and g++ version 4.8.2.
Make relinks your project because it tries to build all. The rule for all does not create any file named all. Instead it produces myexe. Next time you run make, it will see that there's no all, but there's a rule to build one, so it dutifully executes that rule which happens to link myexe every time you run make.
In order to fix your problem you need to change your makefile to look roughly like this:
all: myexe
echo Build done
myexe: <myexe dependencies go here>
$(CXX) $(CFLAGS) -o myexe $(wildcard *.o) $(LDFLAGS)
Make always tries to build the top rule. For you, this is all. Since your all rule doesn't actually make an all file it will always be run.
Your probably want your all rule to be a myexe rule and, if you want an explicit all rule, have a dependency only rule: all: myexe.
(With GNU Make, you might want to explicitly declare those targets which aren't supposed to generate a real file with a .PHONY rule. e.g. .PHONY: all depend clean.)
make is a rule-based expert system.
You give it a heap of rules and a target (default target is the first one listed), and then it builds a complete dependency tree.
All parts are rebuilt iff they are non-existent resp. older than their dependencies, recursively.
The rule you are stumbling over is this: Because the target all does not create an output file all, make invokes the non-existent-or-outdated rule.
You can correct this by making the target all not do any work but instead just depend on the output file. Marking it .PHONY is also a good idea.
Here are my two questions:
I am now learning to manage my code with CVS, and I just want to make a repository for my C++ files, Makefile and bash and python scripts only, not the object files and executables. So I made several subdirectories under my project directory: src, bin, scripts, results and data.
I put C++ files and Makefile under ~/myproject/src, Bash and Python scripts under ~/myproject/scripts and object and executables under ~/myproject/bin. I am hoping only the files under src and scripts will be updated via CVS. I wonder how you organize your projects? Just hope to follow some good habits.
Since I put my C++ files and Makefile into ~/myproject/src and object and executable files into ~/myproject/bin, I have to specify the directories in Makefile. Here is what I am doing
Makefile:
...
BIN_DIR=/home/myproject/bin/
all: $(BIN_DIR)myexecutable TAGS
TAGS: *.cc *.h
etags --members --declarations -l c++ *.cc *.h
$(BIN_DIR)myexecutable: $(BIN_DIR)myobject.o
$(CXX) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
Makefile.depend: *.h *.cc Makefile
$(CXX) -M $(CXXFLAGS) *.cc > Makefile.depend
clean:
\rm -f $(BIN_DIR)myexecutable $(BIN_DIR)*.o Makefile.depend TAGS`
However this will give error
make: *** No rule to make target /home/myproject/bin/myobject.o', needed by /home/myproject/bin/myexecutable'.
How to specify a different directory for object and executable files from C++ files in Makefile?
If you want to learn make, the GNU make manual is very good, both as a reference and a tutorial. You might want to consider using the patsubst command. The following is a chopped down version of one of my own makefiles that uses it:
OUT = bin/csvfix.exe
CC = g++
IDIR = inc
ODIR = obj
SDIR = src
INC = -Iinc -I../alib/inc
LIBS = ../alib/lib/alib.a -lodbc32
_OBJS = csved_atable.o \
csved_case.o \
csved_cli.o \
csved_command.o \
csved_date.o \
OBJS = $(patsubst %,$(ODIR)/%,$(_OBJS))
$(ODIR)/%.o: $(SDIR)/%.cpp
$(CC) -c $(INC) -o $# $< $(CFLAGS)
$(OUT): $(OBJS)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
strip $(OUT)
clean:
rm -f $(ODIR)/*.o $(OUT)
You can keep your files in different directories if you like, but that isn't necessary. Add a file or directory to the CVS repository once, and CVS will retain it indefinitely. From then on you can update it, check it in, whatever. If you don't add an object file to the repository, CVS won't touch it. If you want to add a whole directory tree, and you're in the habit of keeping objects there, just make clean before you do it.
Make is a wonderful tool, but it has some glaring faults. What you're describing is one of the classic problems: Make is good at using a source there to make something here, but not the other way around. Here are a couple of ways to do what you're trying to do.
A) Run make in your binary directory:
...
all: myexecutable TAGS
myexecutable: myobject.o
$(CXX) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
VPATH = /home/myproject/src
...
cd ~/myproject/bin
make -f ../src/makefile
B) Put the objects on the bin directory by brute force:
$(BIN_DIR)%.o: %.cc
$(CXX) $(CXXFLAGS) -c -o $# $^
This will give you a problem with Makefile.depend, which you can approach several ways.
C) Learn some more advanced Make techniques. You probably shouldn't try this yet.
Your directory structure seems sensible.
I would make an explicit rule for executing the compiler, like
TARGET_DIR=bin
SRC_DIR=src
CXX=g++
CXXFLAGS=
ETC=
OBJS=$(TARGET_DIR)/test.o
all: $(OBJS)
$(TARGET_DIR)/%.o: $(SRC_DIR)/%.cc
$(CXX) -c -o $# $(CXXFLAGS) $(ETC) $<
Use automake and autoconf for building your project.
As for the structure of files just look at any big open-source C++ application. Any KDE application
will do fine for that matter. If you find an application that uses C++ and Python even better.
Why not go for eclipse, which is quite popular and handy for managing large projects. You can make a new project in eclipse, import-export code into the project from other projects, does version control for you as well etc. No need to write your make files, eclipse does it for you with your mentioned preferences in GUI.
If you are involved in a C++ project, just install the CDT plugin over eclipse and your are done.
I've looking to find a simple recommended "minimal" c++ makefile for linux which will use g++ to compile and link a single file and h file. Ideally the make file will not even have the physical file names in it and only have a .cpp to .o transform. What is the best way to generate such a makefile without diving into the horrors of autoconf?
The current dir contains, for example
t.cpp
t.h
and I want a makefile for that to be created. I tried autoconf but its assuming .h is gcc instead of g++. Yes, while not a beginner, I am relearning from years ago best approaches to project manipulation and hence am looking for automated ways to create and maintain makefiles for small projects.
If it is a single file, you can type
make t
And it will invoke
g++ t.cpp -o t
This doesn't even require a Makefile in the directory, although it will get confused if you have a t.cpp and a t.c and a t.java, etc etc.
Also a real Makefile:
SOURCES := t.cpp
# Objs are all the sources, with .cpp replaced by .o
OBJS := $(SOURCES:.cpp=.o)
all: t
# Compile the binary 't' by calling the compiler with cflags, lflags, and any libs (if defined) and the list of objects.
t: $(OBJS)
$(CC) $(CFLAGS) -o t $(OBJS) $(LFLAGS) $(LIBS)
# Get a .o from a .cpp by calling compiler with cflags and includes (if defined)
.cpp.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $<
Here is a generic makefile from my code snippets directory:
SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
DEPS=$(SOURCES:.cpp=.d)
BINS=$(SOURCES:.cpp=)
CFLAGS+=-MMD
CXXFLAGS+=-MMD
all: $(BINS)
.PHONY: clean
clean:
$(RM) $(OBJECTS) $(DEPS) $(BINS)
-include $(DEPS)
As long as you have one .cpp source producing one binary, you don't need anything more. I have only used it with GNU make, and the dependency generation uses gcc syntax (also supported by icc). If you are using the SUN compilers, you need to change "-MMD" to "-xMMD". Also, ensure that the tab on the start of the line after clean: does not get changed to spaces when you paste this code or make will give you a missing separator error.
Have you looked at SCons?
Simply create a SConstruct file with the following:
Program("t.cpp")
Then type:
scons
Done!
Assuming no preconfigured system-wide make settings:
CXX = g++
CPPFLAGS = # put pre-processor settings (-I, -D, etc) here
CXXFLAGS = -Wall # put compiler settings here
LDFLAGS = # put linker settings here
test: test.o
$(CXX) -o $# $(CXXFLAGS) $(LDFLAGS) test.o
.cpp.o:
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<
test.cpp: test.h
a fairly small GNU Makefile, using predefined rules and auto-deps:
CC=c++
CXXFLAGS=-g -Wall -Wextra -MMD
LDLIBS=-lm
program: program.o sub.o
clean:
$(RM) *.o *.d program
-include $(wildcard *.d)
Have you looked at OMake ?
OMakeroot
open build/C
DefineCommandVars()
.SUBDIRS: .
OMakefile
.DEFAULT: $(CXXProgram test, test)
Then on Linux or Windows, simply type:
omake
As a bonus, you automatically get:
parallel builds with the -j option (same as make).
MD5 checksums instead of timestamps (build becomes resilient to time synchronization failures).
Automatic and accurate C/C++ header dependencies.
Accurate inter-directory dependencies (something that recursive make does not offer).
Portability (1 build chain to rule them all, immune to path style issues).
A real programming language (better than GNU make).
Some good references on creating a basic Makefile
http://en.wikipedia.org/wiki/Make_(software)
http://mrbook.org/tutorials/make/
http://www.opussoftware.com/tutorial/TutMakefile.htm
http://www.hsrl.rutgers.edu/ug/make_help.html
The first couple in particular have minimal example Makefiles like you were describing. Hope that helps.
SConstruct with debug option:
env = Environment()
if ARGUMENTS.get('debug', 0):
env.Append(CCFLAGS = ' -g')
env.Program( source = "template.cpp" )
florin has a good starting point. I didn't like gnu autoconf so I started there and took the concept further and called it the MagicMakefile. I have 3 versions of it from simple to more complex. The latest is now on github: https://github.com/jdkoftinoff/magicmake
Basically, it assumes you have a standard layout for the source files of your project and uses the wildcard function to create the makefile rules on the fly which are then eval'd, handling header file dependancies, cross compiling, unit tests, install, and packaging.
[edit] At this point I use cmake for all my projects since it generates useful project files for many build systems.
jeff koftinoff
I was hunting around for what a minimal Makefile might look like other than
some_stuff:
#echo "Hello World"
I know I am late for this party, but I thought I would toss my hat into the ring as well. The following is my one directory project Makefile I have used for years. With a little modification it scales to use multiple directories (e.g. src, obj, bin, header, test, etc). Assumes all headers and source files are in the current directory. And, have to give the project a name which is used for the output binary name.
NAME = my_project
FILES = $(shell basename -a $$(ls *.cpp) | sed 's/\.cpp//g')
SRC = $(patsubst %, %.cpp, $(FILES))
OBJ = $(patsubst %, %.o, $(FILES))
HDR = $(patsubst %, -include %.h, $(FILES))
CXX = g++ -Wall
%.o : %.cpp
$(CXX) $(HDR) -c -o $# $<
build: $(OBJ)
$(CXX) -o $(NAME) $(OBJ)
clean:
rm -vf $(NAME) $(OBJ)
If your issues are because autoconf thinks the .h file is a c file, try renaming it to .hpp or .h++