summaryrefslogtreecommitdiff
path: root/mk/Readme.txt
diff options
context:
space:
mode:
Diffstat (limited to 'mk/Readme.txt')
-rw-r--r--mk/Readme.txt469
1 files changed, 0 insertions, 469 deletions
diff --git a/mk/Readme.txt b/mk/Readme.txt
deleted file mode 100644
index c341b48..0000000
--- a/mk/Readme.txt
+++ /dev/null
@@ -1,469 +0,0 @@
-################################################################################
-# Non-recursive make build system #
-# ------------------------------- #
-# Copyright (C) 2012 Andrzej Ostruszka <andrzej.ostruszka@gmail.com> #
-# #
-# URL: http://github.com/aostruszka/nonrec-make #
-# (or older: http://nonrec-make.googlecode.com/) #
-# #
-# Permission is hereby granted, free of charge, to any person obtaining a copy #
-# of this software and associated documentation files (the "Software"), to #
-# deal in the Software without restriction, including without limitation the #
-# rights to use, copy, modify, merge, publish, distribute, sublicense, #
-# and/or sell copies of the Software, and to permit persons to whom the #
-# Software is furnished to do so, subject to the following conditions: #
-# #
-# The above copyright notice and this permission notice shall be included in #
-# all copies or substantial portions of the Software. #
-# #
-# Except as contained in this notice, the name(s) of the above copyright #
-# holders shall not be used in advertising or otherwise to promote the sale, #
-# use or other dealings in this Software without prior written authorization. #
-# #
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS #
-# IN THE SOFTWARE. #
-################################################################################
-
-NOTE: This readme _might_ not be up to date. For up to date information
-see the above URL (and accompanying wiki pages).
-
-This is my attempt to implement a non-recursive make build system. For
-the motivation Google for the paper "Recursive make consider harmful" by
-Peter Miller.
-
-I've seen couple of other proposals and decided to have something that
-will be a blend of nice ideas I have seen plus some improvements. If
-you actually use this I'd like to hear from you :) - is it useful, does
-it perform well, do you have any suggestions for the improvements ...
-and so on. This implementation is based on GNU make and its new
-features introduced in 3.80. But don't use that version - these
-features had bugs in that version. Use version 3.81 where everything
-works OK.
-
-Before you keep on reading though, just take a look at the structure of
-the Rules.mk files (Rules.top has exactly the same structure as Rules.mk
-- it just has another name to ease location of the top level project
-directory from its subfolders).
-I've got a feeling that it is much easier to understand how the system
-looks from the user perspective just by looking at the example than
-reading its explanation :D.
-
-OK, now that you have a feeling how the Rules.mk look like let me walk
-you through an example (ex1 in the repository). Consider the project
-that has some source files at the top directory and is depending on two
-libraries in Dir_1 and Dir_2 and another one in Dir_3. The libraries
-themselves are partitioned between several subdirectories and Dir_2 has
-some examples in a separate subfolder (do not pay attention to all *.c
-files).
-
-ex1/
- Makefile
- Rules.top <- Just a symlink to Rules.mk to mark where the top level is
- Rules.mk
- main.c
- top_a.c
- top_b.c
- cli.c
- cli_dep.c
- mk/* <- This is where the mk files from this build system are
- Dir_1/
- Makefile
- Rules.mk
- dir_1_file1.c
- dir_1_file2.c
- dir_1_file3.c
- Dir_1a/
- Makefile
- Rules.mk
- dir_1a_file1.c
- dir_1a_file2.c
- dir_1a_file3.c
- Dir_1b/
- Makefile
- Rules.mk
- src/
- dir_1b_file1.c
- dir_1b_file2.c
- Dir_2/
- Makefile
- Rules.mk
- dir_2_file1.c
- dir_2_file2.c
- Dir_2a/
- Makefile
- Rules.mk
- dir_2a_file1.c
- dir_2a_file2.c
- dir_2a_file3.c
- Dir_2b/
- Makefile
- Rules.mk
- dir_2b_file1.c
- dir_2b_file2.c
- dir_2b_file3.c
- Dir_ex/
- Makefile
- Rules.mk
- ex.c
- Dir_3/
- Makefile
- Rules.mk
- dir_3_file1.c
- dir_3_file2.c
-
-There's one top level make file (Rules.top) which eventually includes
-all the makefiles. In addition in each directory there is Makefile
-(which can be a link to the one in the top level directory) which
-searches for the Rules.top includes it with the default goal
-changed to rebuild only targets for the current directory. This allows
-you to run make from each subdirectory and update only part of the
-targets (in contrary to other implementation which usually require
-you to run it at the top level and make full build each time).
-
-This build system was designed to have very simple structure of the
-"user makefiles". The user just has to set the Rules.mk files in each
-directory and some general configuration options. All the "magic" is
-hidden in header.mk, footer.mk and skel.mk which don't have to be
-modified [1].
-
-The structure of the Rules.mk is following (this is from top level
-Rules.top which has the same format as Rules.mk - and in fact it is
-suggested that it should be a symlink to normal Rules.mk file since it
-will allow for this project to act as a subproject of some super project
-treating your whole project tree as a subdirectory[2]):
-
--8<---Rules.top---------------
-1: TARGETS = app.exe cli.exe
-2: SUBDIRS = Dir_1 Dir_2
-3:
-4: app.exe_DEPS = top_a.o top_b.o main.o $(SUBDIRS_TGTS)
-5: app.exe_LIBS = -lm
-6: # Let's use DEFAULT_MAKECMD for app.exe
-7:
-8: cli.exe_DEPS = cli.o cli_dep.o
-9: cli.exe_CMD = $(LINK.c) $^ $(LDLIBS) -o $@
--8<---------------------------
-
-Line 1 - this directory has two targets that should be built.
-Line 2 - this directory has two subdirectories that should be scanned
-Line 4 - app.exe depends on ... (SUBDIRS_TGTS is a variable that
- contains all the targets from the subdirectories mentioned at
- line 4)
-Line 5 - app.exe should be linked with math library
-Line 6 - app.exe will be built with default "rule"
-Line 8 - cli.exe depends on ... and
-Line 9 - use the following command to build it
-
-You can specify the targets for current directory in two ways:
-1. Give them in TARGETS. Each target can have it's own *_DEPS, *_LIBS
- and *_CMD which give the dependencies, additional libs needed and
- a command to run which will update the target. They are explained
- a bit below.
-2. The targets are simply objects - or in more general files that
- match patterns in AUTO_TGTS, and have appropriate rules in 'skeleton'.
- In that case you can list them in OBJS or SRCS like e.g. in Rules.mk
- from Dir_1a
-
--8<---Dir_2/Dir_2a/Rules.mk---
-1: SRCS := dir_2a_file1.c dir_2a_file2.c dir_2a_file3.c
--8<---------------------------
-
-There are "reserved" variables that you should not modify. Most notably:
-- $(d) is the directory of the current Rules.mk [see note 2]
-- $(TOP) is the top level directory of the project tree
-- $(MK) is the directory where the included *.mk makefiles are
-For the full list you have to take a look at the makefiles in mk
-directory (e.g. in the skel.mk there are macros 'include_subdir_rules',
-'save_vars', 'tgt_rule' and 'skeleton' which you should not change [1]).
-
-Going back to the Rules.mk. Normally wildcards in variable assignments
-are not expanded in make but this make system detects wildcards in SRCS
-and expands them (both in directory of the Rules.mk and its SRCS_VPATH
-subdirectories - see below what SRCS_VPATH is used for). Thus you can
-simply say in Rules.mk:
-
-SRCS := *.c
-
-If you have directory with large number of files where simple glob is
-what you want to use in SRCS but there are some files that you'd like to
-exclude just list them in SRCS_EXCLUDES :) - this is a list of makefile
-patterns e.g.
-
-SRCS_EXCLUDES := extra% test%
-
-Of course you can use the built in make wildcards but you should do that
-as follows:
-
-SRCS := $(notdir $(wildcard $(d)/*.c))
-
-Keep in mind that the directory where make is invoked is usually different
-from where given Rules.mk is located.
-
-When supplying the value for *_DEPS you can refer to the object from the
-same directory with no directory prefix. To be specific all
-dependencies that are not absolute paths will be treated as ones from
-the $(OBJDIR) subdirectory of current directory (OBJDIR and OBJPATH are
-"discussed" below). You can use SUBDIRS_TGTS variable which will list
-all targets in subdirectories. You can also name them explicitly like
-$(TARGETS_$(d)/subdir) and so on - see e.g. the Rules.mk in Dir_2
-directory where Dir_ex is mentioned as a subdirectory but is excluded
-from the *_DEPS (this allows you to create folders that "inherit" all
-the setting from the project build system but are not meant to be a part
-of the project itself - like examples). For instance:
-
-dir1_lib.a_DEPS = dir_1_file1.o dir_1_file2.o dir_1_file3.o $(SUBDIRS_TGTS)
-
-tells that dir1_lib.a (which will be created in Dir_1/$(OBJDIR)) depends
-on several object files from the same directory and the targets from all
-subdirectories.
-
-One last thing about the TARGETS/OBJS. By default source files for the
-objects are searched in the directory where Rules.mk is, but if you want
-to have source files in a subdirectory (say 'src') you can do that via
-SRCS_VPATH variable (see skel.mk). E.g.:
-
-SRCS_VPATH := src1 src2
-
-will cause make to first look at the directory where Rules.mk is present
-and then in its src1 and src2 subdirectories.
-
-*_LIBS are appended to the LDLIBS variable when updating the target.
-This variable is used by several make built in rules but if you create
-your own rule or MAKECMD.* (see next paragraph) you can refer to it (see
-the function 'save_vars').
-
-When *_CMD is not present and the target does not match any pattern in
-AUTO_TGTS then either MAKECMD.suff (where .suff is the suffix of the
-target) or DEFAULT_MAKECMD is used - take a look into skel.mk.
-
-If you want to setup special flags for compilation you can do that via
-"directory specific variables". As an example here's what I did for
-compilation of C files. There's a built in rule in make which uses
-COMPILE.c variable for making %.o out of %.c so I added $(DIR_CFLAGS) to
-its default value and DIR_CFLAGS is defined in skel.mk as:
-
-DIR_INCLUDES = $(addprefix -I,$(INCLUDES_$(<D)))
-DIR_CFLAGS = $(CFLAGS_$(<D)) $(DIR_INCLUDES)
-
-So it extracts the directory part of the first prerequisite in the rule
-(that is %.c file - check the section 'automatic variables' in make
-manual for the meaning of $(<) and $(<D)) and refer to variables named
-CFLAGS_the_directory_part and INCLUDES_the_directory_part.
-Thus if you wanted to add special includes for files in Dir_1/Dir_1b you
-could add:
-
-INCLUDES_$(d) := $(TOP)/some/special/include_dir
-
-into its Rules.mk and all files in this directory will be compiled with
--I$(TOP)/some... switch. The same goes for CFLAGS and CXXFLAGS.
-
-The same goes for the linker flags - quoting from skel.mk:
-
-LDFLAGS = $(addprefix -L,$(LIBDIRS_$(subst /$(OBJDIR),,$(@D))))
-LDLIBS = $(LIBS_$(@))
-
-The above means that if targets in given directory need to be linked
-with special -L switches you can provide them via LIBDIRS_$(d)
-variables. If there are some global -L switches just append them in
-skel.mk. The second line above shows how *_LIBS variable that you can
-give for specific target gets added to the LDLIBS (there's 'save_vars'
-in between if you're curious :)).
-
-You can of course use target specific variables that GNU make supports
-so you have more control (if you don't know what target specific
-variables are take a look into manual). Say you want to compile
-dir_1b_file2.c with an additional flag but all other files in
-Dir_1/Dir_1b directory should not have this flag turned on. All you
-need to do is to add this line into Rules.mk in Dir_1b directory.
-
-$(OBJPATH)/dir_1b_file2.o : CFLAGS += -ansi
-
-OBJPATH is a variable that contains the full directory where the
-resulting object file will be placed. While we are at this, by default
-all targets are compiled into OBJDIR (defined in skel.mk as 'obj')
-subdirectory of the directory where Rules.mk is present. You can use
-this OBJDIR variable (and perhaps some conditional statements) to setup
-the output path according to your current compilation mode. E.g.
-obj/debug for objects with debugging information or obj/ppc_7xx for
-cross compilation to the given Power PC family and so on. There's
-predefined (in config* files) HOST_ARCH variable that you can use for
-this (e.g. set OBJDIR := obj/$(HOST_ARCH) in skel.mk).
-
-Finally let me explain what targets are defined and the way you can run
-them from command line. By default (that is if you have not modified
-anything :)) there are several targets that are "global". It is 'all',
-'clean_all' and 'dist_clean'. If you specify them in the command line
-they will respectively rebuild whole tree, clean everything and clean
-everything together with the removal of OBJDIRs - no matter from which
-directory you started make. BTW if there's something that you want to
-clean up and it's not in the OBJDIR - e.g. you've got file lexer.l out
-of which lexer.c and lexer.h is generated and you want them to be
-removed - you can specify this in the variable CLEAN (this is relative
-to the directory where Rules.mk is).
-In addition to those each dir has "it's own" targets. These are:
-
-1) dir_<directory_path>
- which builds all targets in given directory plus its dependencies
-2) tree_<directory_path>
- which builds all targets in subtree starting at directory given
-3) clean_<directory_path>
- which removes all "products" from the $(OBJDIR) subdirectory of
- current directory
-4) clean_tree_<directory_path>
- which does clean_<directory_path> and the same for each its
- subdirectory
-
-For your convenience there are couple "aliases" defined (see Makefile).
-When no target is given on command line it defaults to dir_$(pwd).
-If you give 'clean' as a target that will result in execution of target
-clean_$(pwd) and the same for 'clean_tree'. E.g. say you're in Dir_1.
-Then:
-
-* 'make' (same as 'make dir_$(pwd)')
- builds all targets in the Dir_1 which in our example is
- Dir_1/obj/dir1_lib.a - of course any of its dependencies that are not
- up to date are updated also. This rule has one exception - if your
- Rules.mk has no targets and only SUBDIRS (e.g. you have grouped
- several subdirectories in one directory) then simple 'make' in this
- directory - instead of doing nothing - will build targets of all its
- subdirectories.
-* 'make tree' (same as 'make tree_$(pwd)')
- rebuilds everything in given subtree
-* 'make clean' (same as 'make clean_$(pwd)')
- removes everything from Dir_1/obj/
-* 'make clean_tree (same as 'make clean_tree_$(pwd)')
- cleans Dir_1/obj and Dir_1/Dir_1[abc]/obj
-
-You can obviously provide the path by yourself - it does not have to
-be $(pwd) - and as usual you can build particular object files too e.g.
-'make $(pwd)/obj/dir_1_file1.o'
-
-And that would be it. Gee, so much writing for something that is rather
-simple to use - go ahead and take a look again at these Rules.mk in
-various directories. Setting up you project should be simple by now :).
-
-Have fun!
-
- Andrzej Ostruszka
-
-[1] Unless this build system does not do what you wanted :-P. In that
-case you probably need to spiff it up. So you'll need to
-digest it first and note [3] is my hand at it :).
-
-[2] There is one limitation that you should be aware.
-Prior to commit 070f681 you should not have in your project two "target
-specific" LIBS, LDFLAGS or CMD variables (that is those that are used
-during second phase of make execution) that have the same names! For
-example in one part of your tree you're generating target abc which has
-it's abc_CMD and in the other part another target that has the same name
-and also it's own command. In such case the last assignment to abc_CMD
-will hold and it will be used for both targets. The same goes for LIBS
-and LDFLAGS.
-
-And this also applied to situation when you would like to use two
-subprojects in one larger project. There should be no clash between
-variables from these subprojects.
-
-Starting with commit 070f681 you can have in your (sub)projects two
-LIBS, LDFLAGS or CMD variables. However there is a catch here! Since
-these variables are not mandatory (you don't have to provide them for
-each target) in order to differentiate between case where abc_CMD was
-actually given for this instance of abc target from the situation where
-abc_CMD is still visible from previous instance of abc target those
-abc_(LIBS|LDFLAGS|CMD) variables are cleared once their value is
-used/remembered (see save_vars macro in skel.mk). That means referring
-to these variables outside Rules.mk where they were assigned will not
-work (and even in the same Rules.mk they will work only in case of
-simply expanded variables - not recursive). If you have such need I'd
-advice to introduce your own variable and use this variable in all
-places, e.g.:
-
-MATH_LIBS := -lgsl -lgslcblas -lm
-...
-TARGETS := abc
-
-abc_DEPS = ...
-abc_LIBS = $(MATH_LIBS)
-...
-
-[3] You should know that make works in two phases - first it scans the
-makefiles and then it begins their execution (see discussion of
-'immediate' and 'deferred' in section 'Reading Makefiles' of make
-manual). This implies that the $(d) variable is not valid during
-execution of the commands used for target updates. If you need to refer
-to the directory of the target or prerequisite you should rely on
-automatic variables (@, <, ...) and built in functions (dir, notdir,
-...).
-
-Every Rules.mk (or Rules.top) need to be included in cooperation with
-header.mk and footer.mk. This is now done automatically but in older
-versions this was not so and user had to include them manually.
-The main purpose of header is to clear all variables that you can use
-inside Rules.mk so that values set in one rules file does not propagate
-to other. In addition at the top level it sets the $(d) variable (which
-stands for the directory where the currently included Rules.mk is) and
-includes the skel.mk so the top level Rules.top can have exactly the
-same structure as other Rules.mk.
-
-The skel.mk is a skeleton which defines variables used by make. In
-addition it includes:
-- config.mk - this is a file with the "configuration" for your project
-- def_rules.mk - where to put general rules (e.g. pattern rules). E.g.
- if you want to add a rule that builds %.o out of %.m4 (by running m4
- preprocessor before passing the contents of file to CC) just put it in
- here.
-
-skel.mk also defines some functions like save_vars and tgt_rule
-which are called in the footer.mk. Take a look into make manual for the
-way the functions are defined and called if you're not familiar with it.
-
-include_subdir_rules: This is where I keep track of directory of
- currently included makefile and include the Rules.mk from the
- subdirectories. This function is called in footer.mk in foreach
- loop with a subdirectory name as an argument.
-
-save_vars: This one is very simple it just saves the target specific
- variables under their "full path" variables. E.g.
- dir1_lib.a_DEPS will get saved as DEPS_$(TOP)/Dir_1/obj/dir1_lib.a
- This has two purposes. First it allows you to have targets with
- the same names in different directories (not that I recommend
- this :)) and allows for easier definition of tgt_rules :-P
-
-tgt_rule: This is where the rule for given target is created. First
- I convert all relative dependencies to the absolute ones then
- I include all dependency files (by default they are created as
- side effects during compilation - if your compiler does not
- allow you to do that just make simple shell script that will do
- this). I also append appropriate libs and then issue the rule
- for this target. By using the short circuiting 'or' command
- I give priority to the CMD over MAKECMD.suffix which itself has
- priority over DEFAULT_MAKECMD.
-
-skeleton: This is just a skeleton for compilation of files in given
- directory. If you want to add some rule here then also add
- appropriate pattern to the AUTO_TGTS that will filter out these
- targets and prevent generation of the specific rules via
- tgt_rule function.
-
-The footer.mk is where Rules.mk gets translated into the proper
-makefile. There's not much to explain, just take a look in there.
-First I memorize the targets for given directory (either from OBJS/SRCS
-or from TARGETS) with appropriate directory prefix. If there's need to
-save the target specific *_(CMD|DEP|LIB) I do it. Then I include all
-the Rules.mk from the subdirectories. Then I define the targets for
-given directory either explicitly (like clean_all or clean_$(d)) or by
-evaluation of the 'skeleton' mentioned above or by iterating through all
-targets which do not match AUTO_TGTS and evaluating what tgt_rule
-function for this target has returned.
-
-In case you want to play with these settings make sure you understand
-how make works, what are it's phases, when and how the variables are
-expanded and so on. It will save you a lot of time :).
-
-Best regards
-Andrzej