From 356b4610c9f48d07ce798e8b1fca229e08111f8f Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Thu, 17 Sep 2009 14:07:25 -0300 Subject: [PATCH] Improve include directory handling Remove the $J variable, it was useless for now. Rename $I to the more verbose $(INCLUDE_DIR) since it won't be used very often by the user (makefile writer nor makefile user). The include directory symlink is now handled per-project, allowing the inclusion of sub-project headers more naturally (without requiring to prefix the parent project name and allowing the sub-project to keep its original include directory name). The $P variable is not needed anymore because of this. The makefiles functions changed a little to allow per-project include directory making Lib.mak not include any other files; because of that the "all" rule now uses the "secondary expansion" to calculate the prerequisites (the $(all) variable has not been populated yet when the "all" rule is defined). The Toplevel.mak files are now guarded to avoid multiple inclusions. This should be not a problem since now the Toplevel.mak should not be changed, is like an extension to Lib.mak that the user shouldn't mdify unless he is hacking the build system. The subproj is now renamed to otherproj to illustrate how the sub-directory where it is stored doesn't have to match the name of the sub-project. The pre-compiled headers feature is a little broken for now because the system includes detection is too weak to differentiate things real system includes from things included from $(INCLUDE_DIR). --- Build.mak | 3 +- Lib.mak | 54 +++++++++++++++++------------- Toplevel.mak | 9 +++-- lib2/Build.mak | 2 +- lib2/lib2.cpp | 4 +-- subproj/Build.mak | 12 ++++--- subproj/Config.mak | 4 +-- subproj/Toplevel.mak | 9 +++-- subproj/otherproj.c | 9 +++++ subproj/{subproj.h => otherproj.h} | 2 +- subproj/subproj.c | 9 ----- 11 files changed, 66 insertions(+), 51 deletions(-) create mode 100644 subproj/otherproj.c rename subproj/{subproj.h => otherproj.h} (76%) delete mode 100644 subproj/subproj.c diff --git a/Build.mak b/Build.mak index 0f18c0b..45a4740 100644 --- a/Build.mak +++ b/Build.mak @@ -1,4 +1,6 @@ +setup_include_dir__ := $(call symlink_include_dir,remake) + # Include sub-directories makefiles C := subproj @@ -12,4 +14,3 @@ include $T/lib2/Build.mak C := prog include $T/prog/Build.mak - diff --git a/Lib.mak b/Lib.mak index ce54499..106c208 100644 --- a/Lib.mak +++ b/Lib.mak @@ -1,4 +1,3 @@ - ifndef Lib.mak.included Lib.mak.included := 1 @@ -51,11 +50,9 @@ B ?= $G/bin # Libraries directory L ?= $G/lib -# Includes directory -I ?= $G/include -# Generated includes directory -J ?= $G/geninc +# Includes directory +INCLUDE_DIR ?= $G/include # Functions @@ -124,6 +121,13 @@ link = $(call exec,$(LINKER) $(LDFLAGS) $(TARGET_ARCH) -o $@ $1 \ $(patsubst $L/lib%.so,-l%,$(filter %.so,$^)) \ $(foreach obj,$(filter %.o,$^),$(obj))) +# Create a symbolic link to the project under the $(INCLUDE_DIR). The first +# argument is the name of symlink to create. The link is only created if it +# doesn't already exist. +symlink_include_dir = $(shell \ + test -L $(INCLUDE_DIR)/$1 \ + || ln -s $T/$C $(INCLUDE_DIR)/$1 ) + # Overrided flags ################## @@ -132,7 +136,7 @@ link = $(call exec,$(LINKER) $(LDFLAGS) $(TARGET_ARCH) -o $@ $1 \ override CPPFLAGS += -Wall # Use the includes directories to search for includes -override CPPFLAGS += -I$I -I$J +override CPPFLAGS += -I$(INCLUDE_DIR) # Be standard compilant override CFLAGS += -std=c99 -pedantic @@ -175,6 +179,13 @@ COMPILE.cpp.FLAGS := $(CXX) ~ $(CPPFLAGS) ~ $(CXXFLAGS) ~ $(TARGET_ARCH) LINK.o.FLAGS := $(LD) ~ $(LDFLAGS) ~ $(TARGET_ARCH) +# Automatic dependency handling +################################ + +# These files are created during compilation. +sinclude $(shell test -d $O && find $O -name '*.d') + + # Default rules ################ @@ -196,11 +207,15 @@ $L/%.so: $G/link-o-flags clean: $(call exec,$(RM) -r $D,$D) - -# Automatic dependency handling -################################ - -sinclude $(shell test -d $O && find $O -name '*.d') +# These rules use the "Secondary Expansion" GNU Make feature, to allow +# sub-makes to add values to the special variables $(all), after this makefile +# was read. +.SECONDEXPANSION: + +# Phony rule to make all the targets (sub-makefiles can append targets to build +# to the $(all) variable). +.PHONY: all +all: $$(all) # Create build directory structure @@ -215,16 +230,16 @@ gen_rebuild_flags = if test x"$2" != x"`cat $1 2>/dev/null`"; then \ test -f $1 && echo "$3"; \ echo "$2" > $1 ; fi -# Create $O, $B, $L, $I and $J directories and replicate the directory +# Create $O, $B, $L and $(INCLUDE_DIR) directories and replicate the directory # structure of the project into $O. Create one symlink "last" to the current -# build directory and another to use as include directory. It update the flags -# files to detect flag and/or compiler changes to force a rebuild. +# build directory. It update the flags files to detect flag and/or compiler +# changes to force a rebuild. # # NOTE: the second mkdir can yield no arguments if the project don't have any # subdirectories, that's why the current directory "." is included, so it # won't show an error message in case of no subdirectories. setup_build_dir__ := $(shell \ - mkdir -p $O $B $L $I $J; \ + mkdir -p $O $B $L $(INCLUDE_DIR); \ mkdir -p . $(addprefix $O,$(patsubst $T%,%,\ $(shell find $T -type d -not -path '$D*'))); \ $(call gen_rebuild_flags,$G/compile-c-flags, \ @@ -233,7 +248,6 @@ setup_build_dir__ := $(shell \ $(COMPILE.cpp.FLAGS),C++ compiler or flags;); \ $(call gen_rebuild_flags,$G/link-o-flags, \ $(LINK.o.FLAGS),linker or link flags;); \ - test -L $I/$P || ln -s $T $I/$P; \ test -L $D/last || ln -s $F $D/last ) # Print any generated message (if verbose) @@ -241,12 +255,4 @@ $(if $V,$(if $(setup_build_dir__), \ $(info !! Something changed: $(setup_build_dir__) \ re-building affected files...))) -# Include the Build.mak for this directory -include $T/Build.mak - -# Phony rule to make all the targets (sub-makefiles can append targets to build -# to the $(all) variable). -.PHONY: all -all: $(all) - endif diff --git a/Toplevel.mak b/Toplevel.mak index 299722d..f66fec0 100644 --- a/Toplevel.mak +++ b/Toplevel.mak @@ -1,6 +1,5 @@ - -# Project name -P := remake +ifndef Toplevel.mak.included +Toplevel.mak.included := 1 # Load top-level directory local configuration sinclude $T/Config.mak @@ -8,3 +7,7 @@ sinclude $T/Config.mak # Include the build system library include $T/Lib.mak +# Include the Build.mak for this directory +include $T/Build.mak + +endif diff --git a/lib2/Build.mak b/lib2/Build.mak index 02841c5..0d8e02e 100644 --- a/lib2/Build.mak +++ b/lib2/Build.mak @@ -1,5 +1,5 @@ -$L/liblib2.so: $(call find_objects,cpp) $L/liblib1.so $L/libsubproj.so +$L/liblib2.so: $(call find_objects,cpp) $L/liblib1.so $L/libotherproj.so .PHONY: lib2 lib2: $L/liblib2.so diff --git a/lib2/lib2.cpp b/lib2/lib2.cpp index d5c07c4..7555392 100644 --- a/lib2/lib2.cpp +++ b/lib2/lib2.cpp @@ -1,7 +1,7 @@ #include "lib2.h" -#include +#include #include #include @@ -10,6 +10,6 @@ void lib2(void) { printf("lib2()\n"); lib1(); - subproj(); + otherproj(); } diff --git a/subproj/Build.mak b/subproj/Build.mak index 01d8779..353fe83 100644 --- a/subproj/Build.mak +++ b/subproj/Build.mak @@ -1,9 +1,11 @@ -$L/libsubproj.so: LINKER := $(CC) -$L/libsubproj.so: $(call find_objects,c) +setup_include_dir__ := $(call symlink_include_dir,otherproj) -.PHONY: subproj -subproj: $L/libsubproj.so +$L/libotherproj.so: LINKER := $(CC) +$L/libotherproj.so: $(call find_objects,c) -all += subproj +.PHONY: otherproj +otherproj: $L/libotherproj.so + +all += otherproj diff --git a/subproj/Config.mak b/subproj/Config.mak index d7624aa..b02cae7 100644 --- a/subproj/Config.mak +++ b/subproj/Config.mak @@ -3,8 +3,8 @@ T := .. # Include the "parent" project config -sinclude $T/Toplevel.mak +sinclude $T/Config.mak # Include the "parent" project config -.DEFAULT_GOAL := subproj +.DEFAULT_GOAL := otherproj diff --git a/subproj/Toplevel.mak b/subproj/Toplevel.mak index 6109188..f66fec0 100644 --- a/subproj/Toplevel.mak +++ b/subproj/Toplevel.mak @@ -1,6 +1,5 @@ - -# Project name -P := subproj +ifndef Toplevel.mak.included +Toplevel.mak.included := 1 # Load top-level directory local configuration sinclude $T/Config.mak @@ -8,3 +7,7 @@ sinclude $T/Config.mak # Include the build system library include $T/Lib.mak +# Include the Build.mak for this directory +include $T/Build.mak + +endif diff --git a/subproj/otherproj.c b/subproj/otherproj.c new file mode 100644 index 0000000..868f072 --- /dev/null +++ b/subproj/otherproj.c @@ -0,0 +1,9 @@ + +#include "otherproj.h" +#include + +void otherproj(void) +{ + printf("otherproj()\n"); +} + diff --git a/subproj/subproj.h b/subproj/otherproj.h similarity index 76% rename from subproj/subproj.h rename to subproj/otherproj.h index d29126c..5b2d04f 100644 --- a/subproj/subproj.h +++ b/subproj/otherproj.h @@ -3,7 +3,7 @@ extern "C" { #endif -void subproj(void); +void otherproj(void); #ifdef __cplusplus } diff --git a/subproj/subproj.c b/subproj/subproj.c deleted file mode 100644 index 2188e52..0000000 --- a/subproj/subproj.c +++ /dev/null @@ -1,9 +0,0 @@ - -#include "subproj.h" -#include - -void subproj(void) -{ - printf("subproj()\n"); -} - -- 2.43.0