From: Leandro Lucarella Date: Fri, 18 Sep 2009 03:09:24 +0000 (-0300) Subject: Add install and uninstall targets X-Git-Url: https://git.llucax.com/software/makeit.git/commitdiff_plain/cd9d10c747bb0098ccadd2d8211796b38f8ea2ef Add install and uninstall targets The build system now support installing, supporting both $(prefix) and $(DESTDIR) variables. A few helper functions are added to ease installation and the $I variable is provided as the base directory where stuff should be installed (i.e. $(DESTDIR)$(prefix)). The $(prefix) is passed to compiled programs as a pre-processor define (PREFIX) and targets are re-built when it changes. Programs should "register" files to install adding them to the $(install) variable (similar as they register targets to compile in the $(all) variable). A few common rules are included in Lib.mak to install binaries and libraries. To install other type of files the rule should be provided by the makefile writer (but a function is provided to make this easy). The test project is updated to install binaries, libraries and headers. --- diff --git a/Build.mak b/Build.mak index 45a4740..6c44697 100644 --- a/Build.mak +++ b/Build.mak @@ -1,6 +1,11 @@ +# Create the include directory symlink setup_include_dir__ := $(call symlink_include_dir,remake) +# General rule to install headers of this project +$I/include/remake/%.h: $T/%.h + $(call install_file) + # Include sub-directories makefiles C := subproj diff --git a/Lib.mak b/Lib.mak index 539a597..247cad7 100644 --- a/Lib.mak +++ b/Lib.mak @@ -20,6 +20,12 @@ F ?= opt # Use C++ linker by default LINKER := $(CXX) +# Default mode used to install files +IMODE ?= 0644 + +# Degault install flags +IFLAGS ?= -D + # Use precompiled headers if non-empty GCH ?= @@ -27,6 +33,13 @@ GCH ?= # Directories ############## +# Base directory where to install files (can be overrided, should be absolute) +prefix ?= /usr/local + +# Path to a complete alternative environment, usually a jail, or an installed +# system mounted elsewhere than /. +DESTDIR ?= + # Use absolute paths to avoid problems with automatic dependencies when # building from subdirectories T := $(abspath $T) @@ -50,6 +63,8 @@ B ?= $G/bin # Libraries directory L ?= $G/lib +# Installation directory +I := $(DESTDIR)$(prefix) # Includes directory INCLUDE_DIR ?= $G/include @@ -69,6 +84,13 @@ eq = $(if $(subst $1,,$2),,$1) # to the top-level. find_objects = $(patsubst $T/%.$1,$O/%.o,$(shell find $T/$C -name '*.$1')) +# Find sources files and get the corresponding object names +# The first argument should be the sources extension ("c" or "cpp" typically) +# It expects the variable $T and $O to be defined as commented previously in +# this file. $C should be defined to the path to the current directory relative +# to the top-level. +find_headers = $(patsubst $T/$C/%.$1,$2/%.$1,$(shell find $T/$C -name '*.$1')) + # Abbreviate a file name. Cut the leading part of a file if it match to the $T # directory, so it can be displayed as if it were a relative directory. Take # just one argument, the file name. @@ -127,6 +149,13 @@ link = $(call exec,$(LINKER) $(LDFLAGS) $(TARGET_ARCH) -o $@ $1 \ $(patsubst $L/lib%.so,-l%,$(filter %.so,$^)) \ $(foreach obj,$(filter %.o,$^),$(obj))) +# Install a file. All arguments are optional. The first argument is the file +# mode (defaults to 0644). The second argument are extra flags to the install +# command (defaults to -D). The third argument is the source file to install +# (defaults to $<) and the last one is the destination (defaults to $@). +install_file = $(call exec,install -m $(if $1,$1,0644) $(if $2,$2,-D) \ + $(if $3,$3,$<) $(if $4,$4,$@)) + # 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. @@ -144,6 +173,9 @@ override CPPFLAGS += -Wall # Use the includes directories to search for includes override CPPFLAGS += -I$(INCLUDE_DIR) +# Let the program know where it will be installed +override CPPFLAGS += -DPREFIX=$(prefix) + # Be standard compilant override CFLAGS += -std=c99 -pedantic override CXXFLAGS += -std=c++98 -pedantic @@ -196,10 +228,24 @@ $L/%.so: override CXXFLAGS += -fPIC $L/%.so: $G/link-o-flags $(call link,-shared) +$I/bin/%: + $(call install_file,0755) + +$I/sbin/%: + $(call install_file,0755) + +$I/lib/%: + $(call install_file) + .PHONY: clean clean: $(call exec,$(RM) -r $D,$D) +# Phony rule to uninstall all built targets (like "install", uses $(install)). +.PHONY: uninstall +uninstall: + $V$(foreach i,$(install),$(call vexec,$(RM) $i,$i);) + # 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. @@ -210,11 +256,15 @@ clean: .PHONY: all all: $$(all) +# Phony rule to install all built targets (sub-makefiles can append targets to +# build to the $(install) variable). +.PHONY: install +install: $$(install) + # Create build directory structure ################################### - # 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. @@ -233,10 +283,11 @@ setup_build_dir__ := $(shell \ ###################################################### # Re-compile C files if one of this variables changes -COMPILE.c.FLAGS += $(CC) ~ $(CPPFLAGS) ~ $(CFLAGS) ~ $(TARGET_ARCH) +COMPILE.c.FLAGS += $(CC) ~ $(CPPFLAGS) ~ $(CFLAGS) ~ $(TARGET_ARCH) ~ $(prefix) # Re-compile C++ files if one of this variables changes -COMPILE.cpp.FLAGS += $(CXX) ~ $(CPPFLAGS) ~ $(CXXFLAGS) ~ $(TARGET_ARCH) +COMPILE.cpp.FLAGS += $(CXX) ~ $(CPPFLAGS) ~ $(CXXFLAGS) ~ $(TARGET_ARCH) \ + ~ $(prefix) # Re-link binaries and libraries if one of this variables changes LINK.o.FLAGS += $(LD) ~ $(LDFLAGS) ~ $(TARGET_ARCH) diff --git a/lib1/Build.mak b/lib1/Build.mak index 7661dc4..bf29c8f 100644 --- a/lib1/Build.mak +++ b/lib1/Build.mak @@ -1,7 +1,17 @@ +# Build the shared library $L/liblib1.so: LINKER := $(CC) $L/liblib1.so: $(call find_objects,c) +# Nice shortcut target .PHONY: lib1 lib1: $L/liblib1.so +# Install the shared library +$I/lib/liblib1.so: $L/liblib1.so +install += $I/lib/liblib1.so + +# Install the library's headers +# XXX: we can't use += here, call will be resolved lazily if we do +install := $(install) $(call find_headers,h,$I/include/remake/lib1) + diff --git a/lib2/Build.mak b/lib2/Build.mak index 0d8e02e..3ef80b9 100644 --- a/lib2/Build.mak +++ b/lib2/Build.mak @@ -1,6 +1,16 @@ +# Build the shared library $L/liblib2.so: $(call find_objects,cpp) $L/liblib1.so $L/libotherproj.so +# Nice shortcut target .PHONY: lib2 lib2: $L/liblib2.so +# Install the shared library +$I/lib/liblib2.so: $L/liblib2.so +install += $I/lib/liblib2.so + +# Install the library's headers +# XXX: we can't use += here, call will be resolved lazily if we do +install := $(install) $(call find_headers,h,$I/include/remake/lib2) + diff --git a/prog/Build.mak b/prog/Build.mak index d3a59ed..71585a7 100644 --- a/prog/Build.mak +++ b/prog/Build.mak @@ -1,8 +1,13 @@ +# Build the shared library $B/prog: $(call find_objects,cpp) $L/liblib1.so $L/liblib2.so +all += prog +# Nice shortcut target .PHONY: prog prog: $B/prog -all += prog +# Install the program executable +$I/bin/prog: $B/prog +install += $I/bin/prog diff --git a/subproj/Build.mak b/subproj/Build.mak index 353fe83..8236c13 100644 --- a/subproj/Build.mak +++ b/subproj/Build.mak @@ -1,11 +1,23 @@ +# Create the include directory symlink setup_include_dir__ := $(call symlink_include_dir,otherproj) +# Build the shared library $L/libotherproj.so: LINKER := $(CC) $L/libotherproj.so: $(call find_objects,c) +all += otherproj +# Nice shortcut target .PHONY: otherproj otherproj: $L/libotherproj.so -all += otherproj +# Install the shared library +$I/lib/libotherproj.so: $L/libotherproj.so +install += $I/lib/libotherproj.so + +# Install the library's headers +$I/include/otherproj/%.h: $T/$C/%.h + $(call install_file) +# XXX: we can't use += here, call will be resolved lazily if we do +install := $(install) $(call find_headers,h,$I/include/otherproj)