From 4b8459f7aa1d202220593b0c49112892832640ab Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 13:54:11 -0300 Subject: [PATCH 001/153] Move project information to GNUmakefile This information is specific to the project being built and doesn't belong in the make/ directory. --- GNUmakefile | 4 ++++ make/file | 3 +-- make/project | 4 ---- 3 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 make/project diff --git a/GNUmakefile b/GNUmakefile index caa4a9d..96370a9 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1 +1,5 @@ +library := linux +project := lib$(library) +architecture := x86_64 + include make/file diff --git a/make/file b/make/file index 54fb873..efaf7fc 100644 --- a/make/file +++ b/make/file @@ -1,8 +1,7 @@ # Make functions available to the entire build system include make/all_functions -# Project information and file system structure -include make/project +# Project file system structure include make/structure # Integration with project shell scripts diff --git a/make/project b/make/project deleted file mode 100644 index f1c0b58..0000000 --- a/make/project +++ /dev/null @@ -1,4 +0,0 @@ -# Project information -library := linux -project := lib$(library) -architecture := x86_64 From 9372f0ebc95d88fd9dd95a4cdd8d3d22fdbe04e4 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 14:48:17 -0300 Subject: [PATCH 002/153] Define true and false variables in make/logic This makes it easy to use true and false values anywhere in makefiles. --- make/file | 3 +++ make/logic | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 make/logic diff --git a/make/file b/make/file index efaf7fc..6b257ee 100644 --- a/make/file +++ b/make/file @@ -1,3 +1,6 @@ +# Boolean logic in make. +include make/logic + # Make functions available to the entire build system include make/all_functions diff --git a/make/logic b/make/logic new file mode 100644 index 0000000..aea7c15 --- /dev/null +++ b/make/logic @@ -0,0 +1,5 @@ +# Definitions of boolean true and false. +# In Makefiles, the empty string is false and everything else is true. +# +true := ✓ +false := From 8b3194ba73f09d7f433eb8c48d0b76b2ecc0f3b8 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 14:56:22 -0300 Subject: [PATCH 003/153] Define the boolean make function This function converts a value to a truth value. --- make/logic | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/make/logic b/make/logic index aea7c15..a7eea48 100644 --- a/make/logic +++ b/make/logic @@ -3,3 +3,13 @@ # true := ✓ false := + +# Converts the given data to a truth value. +# +# Arguments: +# $(1) = the value to test +# +# Returns: +# $(false) if value is empty, $(true) otherwise +# +boolean = $(if $(1),$(true),$(false)) From 2643f3b3bcb651fd9d3255edc17d5a736a4b310f Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 15:00:05 -0300 Subject: [PATCH 004/153] Define the not make function This is basic and extremely useful functionality that simply isn't provided by make. --- make/logic | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/make/logic b/make/logic index a7eea48..3ac460b 100644 --- a/make/logic +++ b/make/logic @@ -13,3 +13,13 @@ false := # $(false) if value is empty, $(true) otherwise # boolean = $(if $(1),$(true),$(false)) + +# Inverts the truth value of the given data. +# +# Arguments: +# $(1) = the value to test +# +# Returns: +# $(true) if value is empty, $(false) otherwise +# +not = $(if $(1),$(false),$(true)) From 02818d639fe1e3706ba708fb973ea0e6c2c79a3c Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 15:19:17 -0300 Subject: [PATCH 005/153] Define user-friendly symbols for true and false False values are empty. This is an inconvenient representation. Outputting an empty variable can be confusing. A symbol that represents false, though logically true, is much better. --- make/logic | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/make/logic b/make/logic index 3ac460b..0753d24 100644 --- a/make/logic +++ b/make/logic @@ -23,3 +23,13 @@ boolean = $(if $(1),$(true),$(false)) # $(true) if value is empty, $(false) otherwise # not = $(if $(1),$(false),$(true)) + +# User-friendly symbols for true and false. +# +# The boolean symbols provide textual representations for truth values +# because it is inconvenient to output false values as empty text. +# +# Both symbols are logically true. +# +true.symbol := $(true) +false.symbol := ✗ From f259c132aa8780bbc537bb040eadfd5591505321 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 15:30:17 -0300 Subject: [PATCH 006/153] Define the boolean.symbol make function This function converts a value to its symbolic truth value. Useful when outputting a boolean variable as text. --- make/logic | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/make/logic b/make/logic index 0753d24..002adde 100644 --- a/make/logic +++ b/make/logic @@ -33,3 +33,14 @@ not = $(if $(1),$(false),$(true)) # true.symbol := $(true) false.symbol := ✗ + +# Converts the given data to its symbolic truth value. +# The result of this function is never logically false. +# +# Arguments: +# $(1) = the value to test +# +# Returns: +# $(false.symbol) if value is empty, $(true.symbol) otherwise +# +boolean.symbol = $(if $(1),$(true.symbol),$(false.symbol)) From 4762cfad6d86c4d5820fb5cba064c54eed6dbccd Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 16:52:04 -0300 Subject: [PATCH 007/153] Create C.standard variable and default to C99 This allows a project to specify the C standard it wants to use while at the same time providing a sensible default. --- make/compilers/gcc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/make/compilers/gcc b/make/compilers/gcc index 5fdd3b5..0a6098e 100644 --- a/make/compilers/gcc +++ b/make/compilers/gcc @@ -2,6 +2,7 @@ gcc := gcc # GCC option variable and function definitions +gcc_standard_option = -std=$(1) gcc_library_directory_option = -L$(1) gcc_compile_option := -c gcc_preprocess_option := -E @@ -19,14 +20,14 @@ gcc_code_generation_options = $(if $(call equal?,$(1),static),-fno-PIC,-fPIC) gcc_dependency_generation_options = -M -MF $(1) $(foreach target,$(2),-MT $(target)) # Common GCC options -gcc_dialect_options := -ansi -ffreestanding +gcc_dialect_options = $(call gcc_standard_option,$(or $(1),c99)) -ffreestanding gcc_warning_options := -Wall -Wextra -Wpedantic gcc_preprocessor_options := -I $(include_directory) $(gcc_inhibit_linemarkers_option) gcc_optimization_options := -Os -fno-strict-aliasing gcc_instrumentation_options := -fno-stack-protector define gcc_common_options -$(gcc_dialect_options) \ +$(call gcc_dialect_options,$(C.standard)) \ $(gcc_warning_options) \ $(gcc_preprocessor_options) \ $(gcc_optimization_options) \ From 073a361add7af1ba39fb6b0f98b3cdbc1b4e6d5a Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 19:37:43 -0300 Subject: [PATCH 008/153] Use -ffreestanding if C.freestanding is set The new C.freestanding make variable can be set in order to turn on freestanding mode. --- GNUmakefile | 1 + make/compilers/gcc | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 96370a9..ca7baaa 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,5 +1,6 @@ library := linux project := lib$(library) architecture := x86_64 +C.freestanding := yes include make/file diff --git a/make/compilers/gcc b/make/compilers/gcc index 0a6098e..12b8379 100644 --- a/make/compilers/gcc +++ b/make/compilers/gcc @@ -20,14 +20,14 @@ gcc_code_generation_options = $(if $(call equal?,$(1),static),-fno-PIC,-fPIC) gcc_dependency_generation_options = -M -MF $(1) $(foreach target,$(2),-MT $(target)) # Common GCC options -gcc_dialect_options = $(call gcc_standard_option,$(or $(1),c99)) -ffreestanding +gcc_dialect_options = $(strip $(call gcc_standard_option,$(or $(1),c99)) $(if $(2),-ffreestanding)) gcc_warning_options := -Wall -Wextra -Wpedantic gcc_preprocessor_options := -I $(include_directory) $(gcc_inhibit_linemarkers_option) gcc_optimization_options := -Os -fno-strict-aliasing gcc_instrumentation_options := -fno-stack-protector define gcc_common_options -$(call gcc_dialect_options,$(C.standard)) \ +$(call gcc_dialect_options,$(C.standard),$(C.freestanding)) \ $(gcc_warning_options) \ $(gcc_preprocessor_options) \ $(gcc_optimization_options) \ From 05e03d176b9b23f589c2bdc3ac87f7513bfc3f54 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 21:43:54 -0300 Subject: [PATCH 009/153] Define the file? make function Files are defined as entries that are not directories for the purposes of the build system. --- make/functions/file_system | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 make/functions/file_system diff --git a/make/functions/file_system b/make/functions/file_system new file mode 100644 index 0000000..ae2675d --- /dev/null +++ b/make/functions/file_system @@ -0,0 +1,10 @@ +# Determines whether the given path exists and is a file. +# Files are defined as everything that is not a directory. +# +# Arguments: +# $(1) = path to check +# +# Returns: +# whether $(1) refers to an existing file +# +file? = $(call boolean,$(and $(wildcard $(1)),$(call not,$(call directory?,$(1))))) From 7d30eb9bb33cabb3ef523da63a0f3051928643ab Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 22:00:33 -0300 Subject: [PATCH 010/153] Move directory? to make/functions/file_system Also a good opportunity to improve the documentation and convert the result to a boolean value. --- make/all_functions | 1 + make/functions/directory | 12 ------------ make/functions/file_system | 15 +++++++++++++++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/make/all_functions b/make/all_functions index 290f8ee..d155a65 100644 --- a/make/all_functions +++ b/make/all_functions @@ -1,4 +1,5 @@ include make/functions/comparison include make/functions/directory +include make/functions/file_system include make/functions/path include make/functions/shell diff --git a/make/functions/directory b/make/functions/directory index bc21c4f..a4dfe3f 100644 --- a/make/functions/directory +++ b/make/functions/directory @@ -2,18 +2,6 @@ # Should not fail if the directory already exists, and create its parent directories as needed. mkdir_p := mkdir -p -# Determines whether the given path exists and is a directory. -# -# Only existing directories contain a "." entry. -# -# $(1) = path to check -# -# References: -# MadScientist's answer: -# http://stackoverflow.com/a/9456282/512904 -# -directory? = $(wildcard $(1)/.) - # Generates a command that makes sure the given directory exists. # Generates the empty string if the directory already exists. # diff --git a/make/functions/file_system b/make/functions/file_system index ae2675d..f525c04 100644 --- a/make/functions/file_system +++ b/make/functions/file_system @@ -1,3 +1,18 @@ +# Determines whether the given path exists and is a directory. +# Only existing directories contain a "." entry. +# +# Arguments: +# $(1) = path to check +# +# Returns: +# whether $(1) refers to an existing directory +# +# References: +# MadScientist's answer: +# http://stackoverflow.com/a/9456282/512904 +# +directory? = $(call boolean,$(wildcard $(1)/.)) + # Determines whether the given path exists and is a file. # Files are defined as everything that is not a directory. # From a34fbd5c8ba47ac55711f78e60c53a764370ffd8 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 8 May 2019 22:14:28 -0300 Subject: [PATCH 011/153] Define the glob make function This function augments make's built-in wildcard function with a default value, sorting and duplicate removal. --- make/functions/file_system | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/make/functions/file_system b/make/functions/file_system index f525c04..715436b 100644 --- a/make/functions/file_system +++ b/make/functions/file_system @@ -23,3 +23,16 @@ directory? = $(call boolean,$(wildcard $(1)/.)) # whether $(1) refers to an existing file # file? = $(call boolean,$(and $(wildcard $(1)),$(call not,$(call directory?,$(1))))) + +# Returns a sorted list of unique paths matching the specified pattern. +# +# Arguments: +# $(1) = pattern entries must match +# +# Defaults: +# $(1) = * +# +# Returns: +# list of paths matching the specified pattern +# +glob = $(sort $(wildcard $(or $(1),*))) From 8e92bfd812aa3d235e2237e81b6f05ff1dfe53aa Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 9 May 2019 18:20:21 -0300 Subject: [PATCH 012/153] Define the recurse make function This function applies the given function recursively to compute results. --- make/all_functions | 1 + make/functions/recursion | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 make/functions/recursion diff --git a/make/all_functions b/make/all_functions index d155a65..388b6a7 100644 --- a/make/all_functions +++ b/make/all_functions @@ -2,4 +2,5 @@ include make/functions/comparison include make/functions/directory include make/functions/file_system include make/functions/path +include make/functions/recursion include make/functions/shell diff --git a/make/functions/recursion b/make/functions/recursion new file mode 100644 index 0000000..d3e4765 --- /dev/null +++ b/make/functions/recursion @@ -0,0 +1,18 @@ +# Recursively calls a function on lists and aggregates the results. +# +# The base case predicate function takes a list element as argument +# and determines whether it is a base case. +# If an element is a base case, it is returned in the result. +# If an element is not a base case, it is returned in the result +# along with the results of recursing with a new list +# generated by applying the given function to the element. +# +# Arguments: +# $(1) = recursive element generator function +# $(2) = base case predicate function +# $(3) = initial list of values +# +# Returns: +# list containing all recursively computed values +# +recurse = $(foreach x,$(3),$(if $(call $(2),$(x)),$(x),$(x) $(call recurse,$(1),$(2),$(call $(1),$(x))))) From 8fc66d13c617029473908392da6ff7c0fccab35d Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 9 May 2019 18:51:28 -0300 Subject: [PATCH 013/153] Define the glob.default make variable This allows better documentation of the semantics of the default value and reuse of the default value by functions building on top of glob. --- make/functions/file_system | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/make/functions/file_system b/make/functions/file_system index 715436b..e444df8 100644 --- a/make/functions/file_system +++ b/make/functions/file_system @@ -35,4 +35,7 @@ file? = $(call boolean,$(and $(wildcard $(1)),$(call not,$(call directory?,$(1)) # Returns: # list of paths matching the specified pattern # -glob = $(sort $(wildcard $(or $(1),*))) +glob = $(sort $(wildcard $(or $(1),$(glob.default)))) + +# By default, glob with match everything except hidden files in the current directory. +glob.default := * From b8b5d076e3f6afec33bce0a7cc58571b826ce897 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 9 May 2019 18:54:49 -0300 Subject: [PATCH 014/153] Specify the argument that the pattern must match "The specified pattern" is too verbose for the short description of the returned value. It's better to refer to the first argument. --- make/functions/file_system | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/functions/file_system b/make/functions/file_system index e444df8..21a4d9a 100644 --- a/make/functions/file_system +++ b/make/functions/file_system @@ -33,7 +33,7 @@ file? = $(call boolean,$(and $(wildcard $(1)),$(call not,$(call directory?,$(1)) # $(1) = * # # Returns: -# list of paths matching the specified pattern +# list of paths matching $(1) # glob = $(sort $(wildcard $(or $(1),$(glob.default)))) From dae47c2a7d68add1c32268cad410c31c90deb443 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 9 May 2019 19:42:06 -0300 Subject: [PATCH 015/153] Define glob.directory and glob.directory.default This function lists all matching entries in the given directories. By default, it operates on the current directory. --- make/functions/file_system | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/make/functions/file_system b/make/functions/file_system index 21a4d9a..2821e1a 100644 --- a/make/functions/file_system +++ b/make/functions/file_system @@ -39,3 +39,32 @@ glob = $(sort $(wildcard $(or $(1),$(glob.default)))) # By default, glob with match everything except hidden files in the current directory. glob.default := * + +# Returns a sorted list of unique paths inside the specified directory +# that match the specified pattern. +# +# Arguments: +# $(1) = list of directories to work with +# $(2) = pattern entries must match +# +# Defaults: +# $(1) = . +# $(2) = * +# +# Returns: +# list of paths in $(1) matching $(2) +# +# Example: +# +# # Enumerates all entries in the current directory. +# $(call glob.directory) +# +# Example: +# +# # Enumerates all entries in the current directory that start with ".git". +# $(call glob.directory,,.git*) +# +glob.directory = $(call glob,$(addsuffix /$(or $(2),$(glob.default)),$(or $(1),$(glob.directory.default)))) + +# By default, glob.directory operates on the current directory. +glob.directory.default := . From fb5fdf47bbcb9dd8c07101981af823beee5e70fc Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 9 May 2019 20:12:31 -0300 Subject: [PATCH 016/153] Define the file_system.traverse make function This function walks the file system recursively, returning all paths it finds. Should be useful to build lists of all kinds of files. --- make/functions/file_system | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/make/functions/file_system b/make/functions/file_system index 2821e1a..f12aaa6 100644 --- a/make/functions/file_system +++ b/make/functions/file_system @@ -68,3 +68,19 @@ glob.directory = $(call glob,$(addsuffix /$(or $(2),$(glob.default)),$(or $(1),$ # By default, glob.directory operates on the current directory. glob.directory.default := . + +# Traverses the file system recursively. +# +# Arguments: +# $(1) = starting directory +# +# Defaults: +# $(1) = . +# +# Returns: +# list with the contents of the tree rooted in $(1) +# +file_system.traverse = $(call recurse,glob.directory,file?,$(or $(1),$(file_system.traverse.default))) + +# By default, file_system.traverse operates on the current directory. +file_system.traverse.default := . From c83c3bbe8a9c6dcc4f3f949eacc87c33c206162e Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Fri, 10 May 2019 00:27:18 -0300 Subject: [PATCH 017/153] Guard against empty inputs to directory? function Fixes a bug where directory? would always return true if called without any arguments. That happens because the variable would be empty, and the "/." path would have no prefix. The root directory is always a directory by definition. --- make/functions/file_system | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/functions/file_system b/make/functions/file_system index f12aaa6..f59841e 100644 --- a/make/functions/file_system +++ b/make/functions/file_system @@ -11,7 +11,7 @@ # MadScientist's answer: # http://stackoverflow.com/a/9456282/512904 # -directory? = $(call boolean,$(wildcard $(1)/.)) +directory? = $(if $(1),$(call boolean,$(wildcard $(1)/.))) # Determines whether the given path exists and is a file. # Files are defined as everything that is not a directory. From 545ca76b0b330a9deaaf3441e4f95e9fb4f1dd94 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Fri, 10 May 2019 00:32:15 -0300 Subject: [PATCH 018/153] Use addsuffix function to add suffix to variable This allows the user of the function to pass in more than one path. In this case, it will return true if any path refers to a directory. --- make/functions/file_system | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/functions/file_system b/make/functions/file_system index f59841e..261bc89 100644 --- a/make/functions/file_system +++ b/make/functions/file_system @@ -11,7 +11,7 @@ # MadScientist's answer: # http://stackoverflow.com/a/9456282/512904 # -directory? = $(if $(1),$(call boolean,$(wildcard $(1)/.))) +directory? = $(if $(1),$(call boolean,$(wildcard $(addsuffix /.,$(1))))) # Determines whether the given path exists and is a file. # Files are defined as everything that is not a directory. From 2a4d68039b17c7567e848e5d542c9b7bca48e71f Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Fri, 10 May 2019 01:03:31 -0300 Subject: [PATCH 019/153] Define the find make function This function finds all files that satisfy the given predicate function. Extremely useful for finding source files. --- make/functions/file_system | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/make/functions/file_system b/make/functions/file_system index 261bc89..a4f73d3 100644 --- a/make/functions/file_system +++ b/make/functions/file_system @@ -84,3 +84,24 @@ file_system.traverse = $(call recurse,glob.directory,file?,$(or $(1),$(file_syst # By default, file_system.traverse operates on the current directory. file_system.traverse.default := . + +# Walks the directory and returns all files satisfying the predicate function. +# Behaves just like file_system.traverse if not given a predicate function. +# +# Arguments: +# $(1) = starting directory +# $(2) = optional predicate function +# +# Defaults: +# $(1) = . +# $(2) = true +# +# Returns: +# list containing paths in $(1) that satisfy $(2) +# +# Example: +# +# # Find all source files. +# $(call find,source,file?) +# +find = $(foreach entry,$(call file_system.traverse,$(1)),$(if $(call $(or $(2),true),$(entry)),$(entry))) From a4222e05a899ba71ed98c528630b15fed9c60328 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Fri, 10 May 2019 02:42:06 -0300 Subject: [PATCH 020/153] Move source code list variables to GNUmakefile These variables are specific to each project. They don't belong in a modular build system. --- GNUmakefile | 4 ++++ make/file | 3 +-- make/sources | 9 --------- 3 files changed, 5 insertions(+), 11 deletions(-) delete mode 100644 make/sources diff --git a/GNUmakefile b/GNUmakefile index ca7baaa..a971bf3 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,4 +3,8 @@ project := lib$(library) architecture := x86_64 C.freestanding := yes +sources_library = $(call find,$(source_directory),file?) +sources_start = $(call find,$(start_architecture_directory),file?) +sources_examples = $(call glob,$(examples_directory)/*.c) + include make/file diff --git a/make/file b/make/file index 6b257ee..f44d7aa 100644 --- a/make/file +++ b/make/file @@ -14,8 +14,7 @@ include make/all_scripts include make/compiler include make/archiver -# List of sources, headers, examples, objects and targets -include make/sources +# List of headers, examples, objects and targets include make/headers include make/examples include make/objects diff --git a/make/sources b/make/sources deleted file mode 100644 index 6dc6465..0000000 --- a/make/sources +++ /dev/null @@ -1,9 +0,0 @@ -# List of liblinux source code -sources_library := $(wildcard $(source_architecture_directory)/*.c) \ - $(wildcard $(source_directory)/system_calls/*.c) - -# List of liblinux process startup source code -sources_start := $(wildcard $(start_architecture_directory)/*.[csS]) - -# List of example programs that demonstrate how to use liblinux -sources_examples := $(wildcard $(examples_directory)/*.c) From 5e0ab8e628e8489224f0127640ee9ee8234e977b Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Fri, 10 May 2019 02:56:13 -0300 Subject: [PATCH 021/153] Move header file list variable to GNUmakefile This variable is specific to each project. It doesn't belong in a modular build system. --- GNUmakefile | 2 ++ make/file | 3 +-- make/headers | 3 --- 3 files changed, 3 insertions(+), 5 deletions(-) delete mode 100644 make/headers diff --git a/GNUmakefile b/GNUmakefile index a971bf3..10abb17 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,6 +3,8 @@ project := lib$(library) architecture := x86_64 C.freestanding := yes +headers_library = $(call find,$(include_liblinux_directory),file?) + sources_library = $(call find,$(source_directory),file?) sources_start = $(call find,$(start_architecture_directory),file?) sources_examples = $(call glob,$(examples_directory)/*.c) diff --git a/make/file b/make/file index f44d7aa..3767653 100644 --- a/make/file +++ b/make/file @@ -14,8 +14,7 @@ include make/all_scripts include make/compiler include make/archiver -# List of headers, examples, objects and targets -include make/headers +# List of examples, objects and targets include make/examples include make/objects include make/all_targets diff --git a/make/headers b/make/headers deleted file mode 100644 index 83f470e..0000000 --- a/make/headers +++ /dev/null @@ -1,3 +0,0 @@ -# List of liblinux headers -headers_library := $(wildcard $(include_liblinux_directory)/*.h) \ - $(wildcard $(include_liblinux_directory)/system_calls/*.h) From 52209d94eef86eb6d5539b38ec34d68f9c37303b Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Fri, 10 May 2019 02:59:47 -0300 Subject: [PATCH 022/153] Move examples list variable to GNUmakefile This variable is specific to each project. It doesn't belong in a modular build system. --- GNUmakefile | 2 ++ make/examples | 1 - make/file | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 make/examples diff --git a/GNUmakefile b/GNUmakefile index 10abb17..324f9c5 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -9,4 +9,6 @@ sources_library = $(call find,$(source_directory),file?) sources_start = $(call find,$(start_architecture_directory),file?) sources_examples = $(call glob,$(examples_directory)/*.c) +examples = $(basename $(notdir $(sources_examples))) + include make/file diff --git a/make/examples b/make/examples deleted file mode 100644 index 578718c..0000000 --- a/make/examples +++ /dev/null @@ -1 +0,0 @@ -examples := $(basename $(notdir $(sources_examples))) diff --git a/make/file b/make/file index 3767653..626f931 100644 --- a/make/file +++ b/make/file @@ -14,8 +14,7 @@ include make/all_scripts include make/compiler include make/archiver -# List of examples, objects and targets -include make/examples +# List of objects and targets include make/objects include make/all_targets From d2e1273208dd9d41273da1090208b64ada6f879a Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Fri, 10 May 2019 03:09:24 -0300 Subject: [PATCH 023/153] Move object file list variables to GNUmakefile These variables are specific to each project. They don't belong in a modular build system. --- GNUmakefile | 6 ++++++ make/file | 3 +-- make/objects | 14 -------------- 3 files changed, 7 insertions(+), 16 deletions(-) delete mode 100644 make/objects diff --git a/GNUmakefile b/GNUmakefile index 324f9c5..6f26c3d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -11,4 +11,10 @@ sources_examples = $(call glob,$(examples_directory)/*.c) examples = $(basename $(notdir $(sources_examples))) +objects_static_library = $(call source_to_static_object,$(sources_library)) +objects_dynamic_library = $(call source_to_dynamic_object,$(sources_library)) +objects_start = $(call source_to_start_object,$(sources_start)) +objects_libraries = $(objects_static_library) $(objects_dynamic_library) +objects = $(objects_libraries) $(objects_start) + include make/file diff --git a/make/file b/make/file index 626f931..4732ec0 100644 --- a/make/file +++ b/make/file @@ -14,8 +14,7 @@ include make/all_scripts include make/compiler include make/archiver -# List of objects and targets -include make/objects +# List of targets include make/all_targets # Special variables diff --git a/make/objects b/make/objects deleted file mode 100644 index 108971a..0000000 --- a/make/objects +++ /dev/null @@ -1,14 +0,0 @@ -# List of liblinux objects that will be built for the static library -objects_static_library := $(call source_to_static_object,$(sources_library)) - -# List of liblinux objects that will be built for the dynamic library -objects_dynamic_library := $(call source_to_dynamic_object,$(sources_library)) - -# List of liblinux objects that will be built for all libraries -objects_libraries := $(objects_static_library) $(objects_dynamic_library) - -# List of liblinux objects that will be built and used as GCC startfiles -objects_start := $(call source_to_start_object,$(sources_start)) - -# List of all objects -objects := $(objects_libraries) $(objects_start) From 180371a99894a5214a19203e0db4d66d009ae431 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Fri, 10 May 2019 03:18:39 -0300 Subject: [PATCH 024/153] Strip the results of the find make function When find was invoked with a predicate function, the result was the empty string for every path that did not satisfy the predicate function. This resulted in a lot of extraneous white spaces in the positions the paths would have otherwise occupied. Stripping the result gets rid of the spaces. The recurse and file_system.traverse functions didn't need this fix because they always return elements in each iteration of foreach. There are no spaces to strip out. --- make/functions/file_system | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/functions/file_system b/make/functions/file_system index a4f73d3..77141e8 100644 --- a/make/functions/file_system +++ b/make/functions/file_system @@ -104,4 +104,4 @@ file_system.traverse.default := . # # Find all source files. # $(call find,source,file?) # -find = $(foreach entry,$(call file_system.traverse,$(1)),$(if $(call $(or $(2),true),$(entry)),$(entry))) +find = $(strip $(foreach entry,$(call file_system.traverse,$(1)),$(if $(call $(or $(2),true),$(entry)),$(entry)))) From fc3a13a033d588faf055a76c85a4ace0759a4b5e Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 15 May 2019 22:20:06 -0300 Subject: [PATCH 025/153] Move GCC spec and wrapper variables to GNUmakefile These variables are specific to liblinux. --- GNUmakefile | 4 ++++ make/all_scripts | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 6f26c3d..e5a98e1 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -17,4 +17,8 @@ objects_start = $(call source_to_start_object,$(sources_start)) objects_libraries = $(objects_static_library) $(objects_dynamic_library) objects = $(objects_libraries) $(objects_start) +# GCC linker specification file and wrapper script +gcc_specs_script = $(scripts_directory)/$(project).specs.sh +gcc_wrapper_script = $(scripts_directory)/$(project)-gcc.sh + include make/file diff --git a/make/all_scripts b/make/all_scripts index 933cdbf..409a002 100644 --- a/make/all_scripts +++ b/make/all_scripts @@ -1,7 +1,3 @@ -# Project scripts -gcc_specs_script := $(scripts_directory)/$(project).specs.sh -gcc_wrapper_script := $(scripts_directory)/$(project)-gcc.sh - # Scripts must be downloaded from the kernel's git repository download = curl --output $(1) $(2) linux_script_url = https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/scripts/$(1) From 48e8de8c76228df959dcc71bea37a14df6ed11a1 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 15 May 2019 22:28:43 -0300 Subject: [PATCH 026/153] Move build directory variable to build section This variable belongs with the other variables defining the build tree. --- make/structure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/structure b/make/structure index 5fc23fa..34fae55 100644 --- a/make/structure +++ b/make/structure @@ -4,7 +4,6 @@ include_directory := include start_directory := start examples_directory := examples scripts_directory := scripts -build_directory := build source_architecture_directory := $(source_directory)/arch/$(architecture) include_liblinux_directory := $(include_directory)/liblinux @@ -12,6 +11,7 @@ start_architecture_directory := $(start_directory)/$(architecture) scripts_linux_directory := $(scripts_directory)/linux # Directories for build artifacts +build_directory := build build_root_directory := $(build_directory)/$(architecture) build_objects_directory := $(build_root_directory)/objects From fb3d5b840d1b69a2442a37c47d93f8d992b90459 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 15 May 2019 22:32:53 -0300 Subject: [PATCH 027/153] Move include directory variables to GNUmakefile These variables are specific to liblinux. --- GNUmakefile | 4 ++++ make/structure | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index e5a98e1..1e31cc1 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,6 +3,10 @@ project := lib$(library) architecture := x86_64 C.freestanding := yes +# Library headers +include_directory := include +include_liblinux_directory := $(include_directory)/liblinux + headers_library = $(call find,$(include_liblinux_directory),file?) sources_library = $(call find,$(source_directory),file?) diff --git a/make/structure b/make/structure index 34fae55..1f6a57c 100644 --- a/make/structure +++ b/make/structure @@ -1,12 +1,10 @@ # Project file system structure source_directory := source -include_directory := include start_directory := start examples_directory := examples scripts_directory := scripts source_architecture_directory := $(source_directory)/arch/$(architecture) -include_liblinux_directory := $(include_directory)/liblinux start_architecture_directory := $(start_directory)/$(architecture) scripts_linux_directory := $(scripts_directory)/linux From dcaecf1d160684c1247eb2d7c0bb3acf3e990a7c Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 15 May 2019 23:10:15 -0300 Subject: [PATCH 028/153] Move source directory variables to GNUmakefile These variables are specific to liblinux. --- GNUmakefile | 5 ++++- make/structure | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 1e31cc1..fcd3e03 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -9,10 +9,13 @@ include_liblinux_directory := $(include_directory)/liblinux headers_library = $(call find,$(include_liblinux_directory),file?) -sources_library = $(call find,$(source_directory),file?) +# Library sources and objects +source_directory := source +source_architecture_directory := $(source_directory)/arch/$(architecture) sources_start = $(call find,$(start_architecture_directory),file?) sources_examples = $(call glob,$(examples_directory)/*.c) +sources_library = $(call find,$(source_directory),file?) examples = $(basename $(notdir $(sources_examples))) objects_static_library = $(call source_to_static_object,$(sources_library)) diff --git a/make/structure b/make/structure index 1f6a57c..3322a18 100644 --- a/make/structure +++ b/make/structure @@ -1,10 +1,8 @@ # Project file system structure -source_directory := source start_directory := start examples_directory := examples scripts_directory := scripts -source_architecture_directory := $(source_directory)/arch/$(architecture) start_architecture_directory := $(start_directory)/$(architecture) scripts_linux_directory := $(scripts_directory)/linux From df0eadbada3310a87530bb17e2526b548122e35c Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 15 May 2019 23:13:41 -0300 Subject: [PATCH 029/153] Move start directory variables to GNUmakefile These variables are specific to liblinux. --- GNUmakefile | 13 +++++++++++-- make/structure | 2 -- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index fcd3e03..9b7460f 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -12,7 +12,6 @@ headers_library = $(call find,$(include_liblinux_directory),file?) # Library sources and objects source_directory := source source_architecture_directory := $(source_directory)/arch/$(architecture) -sources_start = $(call find,$(start_architecture_directory),file?) sources_examples = $(call glob,$(examples_directory)/*.c) sources_library = $(call find,$(source_directory),file?) @@ -20,8 +19,18 @@ examples = $(basename $(notdir $(sources_examples))) objects_static_library = $(call source_to_static_object,$(sources_library)) objects_dynamic_library = $(call source_to_dynamic_object,$(sources_library)) -objects_start = $(call source_to_start_object,$(sources_start)) + objects_libraries = $(objects_static_library) $(objects_dynamic_library) + +# Process start code +start_directory := start +start_architecture_directory := $(start_directory)/$(architecture) + +sources_start = $(call find,$(start_architecture_directory),file?) + +objects_start = $(call source_to_start_object,$(sources_start)) + +# All objects objects = $(objects_libraries) $(objects_start) # GCC linker specification file and wrapper script diff --git a/make/structure b/make/structure index 3322a18..e2208e7 100644 --- a/make/structure +++ b/make/structure @@ -1,9 +1,7 @@ # Project file system structure -start_directory := start examples_directory := examples scripts_directory := scripts -start_architecture_directory := $(start_directory)/$(architecture) scripts_linux_directory := $(scripts_directory)/linux # Directories for build artifacts From ac6c757cd5279eb768bc48995ac67f03648e2518 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 15 May 2019 23:20:35 -0300 Subject: [PATCH 030/153] Move example directory variable to GNUmakefile This variable is specific to liblinux. --- GNUmakefile | 9 +++++++-- make/structure | 2 -- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 9b7460f..3b1fe9a 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -12,10 +12,8 @@ headers_library = $(call find,$(include_liblinux_directory),file?) # Library sources and objects source_directory := source source_architecture_directory := $(source_directory)/arch/$(architecture) -sources_examples = $(call glob,$(examples_directory)/*.c) sources_library = $(call find,$(source_directory),file?) -examples = $(basename $(notdir $(sources_examples))) objects_static_library = $(call source_to_static_object,$(sources_library)) objects_dynamic_library = $(call source_to_dynamic_object,$(sources_library)) @@ -33,6 +31,13 @@ objects_start = $(call source_to_start_object,$(sources_start)) # All objects objects = $(objects_libraries) $(objects_start) +# Library usage examples +examples_directory := examples + +sources_examples = $(call glob,$(examples_directory)/*.c) + +examples = $(basename $(notdir $(sources_examples))) + # GCC linker specification file and wrapper script gcc_specs_script = $(scripts_directory)/$(project).specs.sh gcc_wrapper_script = $(scripts_directory)/$(project)-gcc.sh diff --git a/make/structure b/make/structure index e2208e7..de00909 100644 --- a/make/structure +++ b/make/structure @@ -1,7 +1,5 @@ # Project file system structure -examples_directory := examples scripts_directory := scripts - scripts_linux_directory := $(scripts_directory)/linux # Directories for build artifacts From da8f517a8652c63005d7abca9373234bbf490da7 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 16 May 2019 00:05:44 -0300 Subject: [PATCH 031/153] Move scripts directory variable to GNUmakefile This variable is specific to liblinux. This allows converting the other script variables into simply expanded variables. --- GNUmakefile | 6 ++++-- make/structure | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 3b1fe9a..38af595 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -39,7 +39,9 @@ sources_examples = $(call glob,$(examples_directory)/*.c) examples = $(basename $(notdir $(sources_examples))) # GCC linker specification file and wrapper script -gcc_specs_script = $(scripts_directory)/$(project).specs.sh -gcc_wrapper_script = $(scripts_directory)/$(project)-gcc.sh +scripts_directory := scripts + +gcc_specs_script := $(scripts_directory)/$(project).specs.sh +gcc_wrapper_script := $(scripts_directory)/$(project)-gcc.sh include make/file diff --git a/make/structure b/make/structure index de00909..3b31547 100644 --- a/make/structure +++ b/make/structure @@ -1,5 +1,4 @@ # Project file system structure -scripts_directory := scripts scripts_linux_directory := $(scripts_directory)/linux # Directories for build artifacts From 4bc5a42b3e3fb0cacdb8b921317fd9817e029589 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 16 May 2019 00:16:22 -0300 Subject: [PATCH 032/153] Move scripts directory variable to GNUmakefile This feature is specific to liblinux. The project follows the Linux kernel coding style. References: https://www.kernel.org/doc/html/latest/process/coding-style.html --- GNUmakefile | 22 ++++++++++++++++++++++ make/all_scripts | 5 ----- make/scripts/checkpatch | 16 ---------------- make/structure | 3 --- 4 files changed, 22 insertions(+), 24 deletions(-) delete mode 100644 make/scripts/checkpatch diff --git a/GNUmakefile b/GNUmakefile index 38af595..19546ee 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -44,4 +44,26 @@ scripts_directory := scripts gcc_specs_script := $(scripts_directory)/$(project).specs.sh gcc_wrapper_script := $(scripts_directory)/$(project)-gcc.sh +# Linux kernel checkpatch script integration +scripts_linux_directory := $(scripts_directory)/linux + +checkpatch.pl := $(scripts_linux_directory)/checkpatch.pl +checkpatch_data_files := $(addprefix $(dir $(checkpatch.pl)),const_structs.checkpatch spelling.txt) + +linux_script_url = https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/scripts/$(1) +download_linux_script = $(call download,$(1),$(call linux_script_url,$(notdir $(1)))) + +$(checkpatch.pl): $(checkpatch_data_files) + $(call download_linux_script,$@) + chmod +x $@ + +$(checkpatch_data_files): + $(call download_linux_script,$@) + +phony_targets += checkpatch +checkpatch: $(checkpatch.pl) + find $(include_directory) $(source_directory) $(start_directory) $(examples_directory) \ + -type f \ + -exec $(checkpatch.pl) --quiet --no-tree --file {} \; + include make/file diff --git a/make/all_scripts b/make/all_scripts index 409a002..5ed73ff 100644 --- a/make/all_scripts +++ b/make/all_scripts @@ -1,6 +1 @@ -# Scripts must be downloaded from the kernel's git repository download = curl --output $(1) $(2) -linux_script_url = https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/scripts/$(1) -download_linux_script = $(call download,$(1),$(call linux_script_url,$(notdir $(1)))) - -include make/scripts/checkpatch diff --git a/make/scripts/checkpatch b/make/scripts/checkpatch deleted file mode 100644 index fcc28c5..0000000 --- a/make/scripts/checkpatch +++ /dev/null @@ -1,16 +0,0 @@ -# Integration with the checkpatch.pl script -checkpatch.pl := $(scripts_linux_directory)/checkpatch.pl -checkpatch_data_files := $(addprefix $(dir $(checkpatch.pl)),const_structs.checkpatch spelling.txt) - -$(checkpatch.pl): $(checkpatch_data_files) - $(call download_linux_script,$@) - chmod +x $@ - -$(checkpatch_data_files): - $(call download_linux_script,$@) - -phony_targets += checkpatch -checkpatch: $(checkpatch.pl) - find $(include_directory) $(source_directory) $(start_directory) $(examples_directory) \ - -type f \ - -exec $(checkpatch.pl) --quiet --no-tree --file {} \; diff --git a/make/structure b/make/structure index 3b31547..566a68d 100644 --- a/make/structure +++ b/make/structure @@ -1,6 +1,3 @@ -# Project file system structure -scripts_linux_directory := $(scripts_directory)/linux - # Directories for build artifacts build_directory := build build_root_directory := $(build_directory)/$(architecture) From 9b3cbfa6c3e33a7bd54475fae14c0e5687b1402d Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 16 May 2019 00:26:05 -0300 Subject: [PATCH 033/153] Convert mkdir_p to a function in make/commands The placement of arguments in the command line should be decided by the function, not its caller. --- make/commands | 11 +++++++++++ make/file | 3 +++ make/functions/directory | 6 +----- 3 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 make/commands diff --git a/make/commands b/make/commands new file mode 100644 index 0000000..1eee32c --- /dev/null +++ b/make/commands @@ -0,0 +1,11 @@ +# Generates a directory creation command. +# Does not fail if the directory already exists. +# Creates all parent directories as needed. +# +# Arguments: +# $(1) = directories to create +# +# Returns: +# command line that creates $(1) +# +mkdir_p = mkdir -p $(1) diff --git a/make/file b/make/file index 4732ec0..ea2caaf 100644 --- a/make/file +++ b/make/file @@ -1,6 +1,9 @@ # Boolean logic in make. include make/logic +# Commands used by the build system +include make/commands + # Make functions available to the entire build system include make/all_functions diff --git a/make/functions/directory b/make/functions/directory index a4dfe3f..5e9b31e 100644 --- a/make/functions/directory +++ b/make/functions/directory @@ -1,13 +1,9 @@ -# Command to use to create directories. -# Should not fail if the directory already exists, and create its parent directories as needed. -mkdir_p := mkdir -p - # Generates a command that makes sure the given directory exists. # Generates the empty string if the directory already exists. # # $(1) = path to directory to create # -ensure_directory_exists = $(if $(call directory?,$(1)),,$(mkdir_p) $(1)) +ensure_directory_exists = $(if $(call directory?,$(1)),,$(call mkdir_p,$(1))) # Ensures the existence of the directory where the target of a rule is located in. # This function references an automatic variable so it should only be used inside recipes. From ef5b61eaaa150627595ab25f2d6c4117723ed8a1 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 16 May 2019 00:39:19 -0300 Subject: [PATCH 034/153] Move download function to make/commands Invert the order of the parameters and update call sites to match. Download X to Y is more natural than download to X, Y. Add detailed documentation for the download function. --- GNUmakefile | 2 +- make/all_scripts | 1 - make/commands | 11 +++++++++++ make/file | 3 --- 4 files changed, 12 insertions(+), 5 deletions(-) delete mode 100644 make/all_scripts diff --git a/GNUmakefile b/GNUmakefile index 19546ee..b4f96cd 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -51,7 +51,7 @@ checkpatch.pl := $(scripts_linux_directory)/checkpatch.pl checkpatch_data_files := $(addprefix $(dir $(checkpatch.pl)),const_structs.checkpatch spelling.txt) linux_script_url = https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/scripts/$(1) -download_linux_script = $(call download,$(1),$(call linux_script_url,$(notdir $(1)))) +download_linux_script = $(call download,$(call linux_script_url,$(notdir $(1))),$(1)) $(checkpatch.pl): $(checkpatch_data_files) $(call download_linux_script,$@) diff --git a/make/all_scripts b/make/all_scripts deleted file mode 100644 index 5ed73ff..0000000 --- a/make/all_scripts +++ /dev/null @@ -1 +0,0 @@ -download = curl --output $(1) $(2) diff --git a/make/commands b/make/commands index 1eee32c..50fef95 100644 --- a/make/commands +++ b/make/commands @@ -9,3 +9,14 @@ # command line that creates $(1) # mkdir_p = mkdir -p $(1) + +# Generates a file download command. +# +# Arguments: +# $(1) = what to download +# $(2) = where to write downloaded data to +# +# Returns: +# command line that downloads $(1) to $(2) +# +download = curl --output $(2) $(1) diff --git a/make/file b/make/file index ea2caaf..2cdd503 100644 --- a/make/file +++ b/make/file @@ -10,9 +10,6 @@ include make/all_functions # Project file system structure include make/structure -# Integration with project shell scripts -include make/all_scripts - # Compiler and archiver configuration include make/compiler include make/archiver From f5ccc92bef373bb9319f54653b2871154e81f199 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 16 May 2019 00:43:44 -0300 Subject: [PATCH 035/153] Remove trailing dot from comment Increases consistency with existing comments. --- make/file | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/file b/make/file index 2cdd503..433be34 100644 --- a/make/file +++ b/make/file @@ -1,4 +1,4 @@ -# Boolean logic in make. +# Boolean logic in make include make/logic # Commands used by the build system From c651310222fae39d33ac3f6476e03d394988c02d Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 19 May 2019 16:40:06 -0300 Subject: [PATCH 036/153] Rename make/ to .make/ and update includes Hiding the build system framework directory frees up the make directory for the user. --- .gitattributes | 2 +- .make/all_functions | 6 +++++ .make/all_targets | 26 +++++++++++++++++++ {make => .make}/archiver | 0 {make => .make}/commands | 0 {make => .make}/compiler | 2 +- {make => .make}/compilers/gcc | 0 {make => .make}/file | 14 +++++----- {make => .make}/functions/comparison | 0 {make => .make}/functions/directory | 0 {make => .make}/functions/file_system | 0 {make => .make}/functions/path | 0 {make => .make}/functions/recursion | 0 {make => .make}/functions/shell | 0 {make => .make}/logic | 0 {make => .make}/structure | 0 {make => .make}/targets/all_phony | 4 +-- {make => .make}/targets/dependencies | 0 {make => .make}/targets/dynamic_library | 0 {make => .make}/targets/examples | 0 {make => .make}/targets/gcc_wrapper | 0 {make => .make}/targets/objects | 0 {make => .make}/targets/phony/examples | 0 {make => .make}/targets/phony/system_calls | 0 {make => .make}/targets/start | 0 {make => .make}/targets/static_library | 0 .../targets/system_calls/available | 0 .../targets/system_calls/implemented | 0 {make => .make}/targets/system_calls/missing | 0 GNUmakefile | 2 +- make/all_functions | 6 ----- make/all_targets | 26 ------------------- 32 files changed, 44 insertions(+), 44 deletions(-) create mode 100644 .make/all_functions create mode 100644 .make/all_targets rename {make => .make}/archiver (100%) rename {make => .make}/commands (100%) rename {make => .make}/compiler (97%) rename {make => .make}/compilers/gcc (100%) rename {make => .make}/file (62%) rename {make => .make}/functions/comparison (100%) rename {make => .make}/functions/directory (100%) rename {make => .make}/functions/file_system (100%) rename {make => .make}/functions/path (100%) rename {make => .make}/functions/recursion (100%) rename {make => .make}/functions/shell (100%) rename {make => .make}/logic (100%) rename {make => .make}/structure (100%) rename {make => .make}/targets/all_phony (88%) rename {make => .make}/targets/dependencies (100%) rename {make => .make}/targets/dynamic_library (100%) rename {make => .make}/targets/examples (100%) rename {make => .make}/targets/gcc_wrapper (100%) rename {make => .make}/targets/objects (100%) rename {make => .make}/targets/phony/examples (100%) rename {make => .make}/targets/phony/system_calls (100%) rename {make => .make}/targets/start (100%) rename {make => .make}/targets/static_library (100%) rename {make => .make}/targets/system_calls/available (100%) rename {make => .make}/targets/system_calls/implemented (100%) rename {make => .make}/targets/system_calls/missing (100%) delete mode 100644 make/all_functions delete mode 100644 make/all_targets diff --git a/.gitattributes b/.gitattributes index ae8527a..8dcc477 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -make/** linguist-language=make +.make/** linguist-language=make diff --git a/.make/all_functions b/.make/all_functions new file mode 100644 index 0000000..e81c946 --- /dev/null +++ b/.make/all_functions @@ -0,0 +1,6 @@ +include .make/functions/comparison +include .make/functions/directory +include .make/functions/file_system +include .make/functions/path +include .make/functions/recursion +include .make/functions/shell diff --git a/.make/all_targets b/.make/all_targets new file mode 100644 index 0000000..29909c0 --- /dev/null +++ b/.make/all_targets @@ -0,0 +1,26 @@ +# Object files resulting from the compilation of translation units +include .make/targets/objects + +# The main build targets are the static and dynamic libraries +include .make/targets/static_library +include .make/targets/dynamic_library + +# Targets for the liblinux process startup files +include .make/targets/start + +# GCC wrapper script and the specs file used by it +include .make/targets/gcc_wrapper + +# Targets for library usage examples +include .make/targets/examples + +# Targets for dependency data +include .make/targets/dependencies + +# System call lists +include .make/targets/system_calls/available +include .make/targets/system_calls/implemented +include .make/targets/system_calls/missing + +# Phony targets +include .make/targets/all_phony diff --git a/make/archiver b/.make/archiver similarity index 100% rename from make/archiver rename to .make/archiver diff --git a/make/commands b/.make/commands similarity index 100% rename from make/commands rename to .make/commands diff --git a/make/compiler b/.make/compiler similarity index 97% rename from make/compiler rename to .make/compiler index f8aaaf6..3ff0bad 100644 --- a/make/compiler +++ b/.make/compiler @@ -1,4 +1,4 @@ -include make/compilers/gcc +include .make/compilers/gcc default_compiler := gcc compiler := $(default_compiler) diff --git a/make/compilers/gcc b/.make/compilers/gcc similarity index 100% rename from make/compilers/gcc rename to .make/compilers/gcc diff --git a/make/file b/.make/file similarity index 62% rename from make/file rename to .make/file index 433be34..609ecc2 100644 --- a/make/file +++ b/.make/file @@ -1,21 +1,21 @@ # Boolean logic in make -include make/logic +include .make/logic # Commands used by the build system -include make/commands +include .make/commands # Make functions available to the entire build system -include make/all_functions +include .make/all_functions # Project file system structure -include make/structure +include .make/structure # Compiler and archiver configuration -include make/compiler -include make/archiver +include .make/compiler +include .make/archiver # List of targets -include make/all_targets +include .make/all_targets # Special variables diff --git a/make/functions/comparison b/.make/functions/comparison similarity index 100% rename from make/functions/comparison rename to .make/functions/comparison diff --git a/make/functions/directory b/.make/functions/directory similarity index 100% rename from make/functions/directory rename to .make/functions/directory diff --git a/make/functions/file_system b/.make/functions/file_system similarity index 100% rename from make/functions/file_system rename to .make/functions/file_system diff --git a/make/functions/path b/.make/functions/path similarity index 100% rename from make/functions/path rename to .make/functions/path diff --git a/make/functions/recursion b/.make/functions/recursion similarity index 100% rename from make/functions/recursion rename to .make/functions/recursion diff --git a/make/functions/shell b/.make/functions/shell similarity index 100% rename from make/functions/shell rename to .make/functions/shell diff --git a/make/logic b/.make/logic similarity index 100% rename from make/logic rename to .make/logic diff --git a/make/structure b/.make/structure similarity index 100% rename from make/structure rename to .make/structure diff --git a/make/targets/all_phony b/.make/targets/all_phony similarity index 88% rename from make/targets/all_phony rename to .make/targets/all_phony index 5ffa7d8..763bcf1 100644 --- a/make/targets/all_phony +++ b/.make/targets/all_phony @@ -28,5 +28,5 @@ phony_targets += clean clean: rm -rf $(build_directory)/ -include make/targets/phony/examples -include make/targets/phony/system_calls +include .make/targets/phony/examples +include .make/targets/phony/system_calls diff --git a/make/targets/dependencies b/.make/targets/dependencies similarity index 100% rename from make/targets/dependencies rename to .make/targets/dependencies diff --git a/make/targets/dynamic_library b/.make/targets/dynamic_library similarity index 100% rename from make/targets/dynamic_library rename to .make/targets/dynamic_library diff --git a/make/targets/examples b/.make/targets/examples similarity index 100% rename from make/targets/examples rename to .make/targets/examples diff --git a/make/targets/gcc_wrapper b/.make/targets/gcc_wrapper similarity index 100% rename from make/targets/gcc_wrapper rename to .make/targets/gcc_wrapper diff --git a/make/targets/objects b/.make/targets/objects similarity index 100% rename from make/targets/objects rename to .make/targets/objects diff --git a/make/targets/phony/examples b/.make/targets/phony/examples similarity index 100% rename from make/targets/phony/examples rename to .make/targets/phony/examples diff --git a/make/targets/phony/system_calls b/.make/targets/phony/system_calls similarity index 100% rename from make/targets/phony/system_calls rename to .make/targets/phony/system_calls diff --git a/make/targets/start b/.make/targets/start similarity index 100% rename from make/targets/start rename to .make/targets/start diff --git a/make/targets/static_library b/.make/targets/static_library similarity index 100% rename from make/targets/static_library rename to .make/targets/static_library diff --git a/make/targets/system_calls/available b/.make/targets/system_calls/available similarity index 100% rename from make/targets/system_calls/available rename to .make/targets/system_calls/available diff --git a/make/targets/system_calls/implemented b/.make/targets/system_calls/implemented similarity index 100% rename from make/targets/system_calls/implemented rename to .make/targets/system_calls/implemented diff --git a/make/targets/system_calls/missing b/.make/targets/system_calls/missing similarity index 100% rename from make/targets/system_calls/missing rename to .make/targets/system_calls/missing diff --git a/GNUmakefile b/GNUmakefile index b4f96cd..bd83c94 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -66,4 +66,4 @@ checkpatch: $(checkpatch.pl) -type f \ -exec $(checkpatch.pl) --quiet --no-tree --file {} \; -include make/file +include .make/file diff --git a/make/all_functions b/make/all_functions deleted file mode 100644 index 388b6a7..0000000 --- a/make/all_functions +++ /dev/null @@ -1,6 +0,0 @@ -include make/functions/comparison -include make/functions/directory -include make/functions/file_system -include make/functions/path -include make/functions/recursion -include make/functions/shell diff --git a/make/all_targets b/make/all_targets deleted file mode 100644 index 69a3575..0000000 --- a/make/all_targets +++ /dev/null @@ -1,26 +0,0 @@ -# Object files resulting from the compilation of translation units -include make/targets/objects - -# The main build targets are the static and dynamic libraries -include make/targets/static_library -include make/targets/dynamic_library - -# Targets for the liblinux process startup files -include make/targets/start - -# GCC wrapper script and the specs file used by it -include make/targets/gcc_wrapper - -# Targets for library usage examples -include make/targets/examples - -# Targets for dependency data -include make/targets/dependencies - -# System call lists -include make/targets/system_calls/available -include make/targets/system_calls/implemented -include make/targets/system_calls/missing - -# Phony targets -include make/targets/all_phony From c6bea5a7b05aaa2211c51775f3ed5014bac81d47 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 19 May 2019 16:55:38 -0300 Subject: [PATCH 037/153] Include make/file if it exists Since the build system framework has been moved to the .make/ directory, the make/ directory is now available for the user. It's the ideal place for makefiles that are too specific for the build system framework. GNUmakefile Includes .make/file .make/ Build system framework .make/file Includes make/file if it exists make/ Project-specific makefiles make/file Included by the framework if it exists This enables several ways to use the framework: - Project specifics in GNUmakefile - Project specifics in make/file - Project specifics in makefiles included by make/file --- .gitattributes | 2 +- .make/file | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 8dcc477..9e3243a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -.make/** linguist-language=make +*make/** linguist-language=make diff --git a/.make/file b/.make/file index 609ecc2..6469908 100644 --- a/.make/file +++ b/.make/file @@ -17,6 +17,9 @@ include .make/archiver # List of targets include .make/all_targets +# Include the user's makefile, if it exists +include $(wildcard make/file) + # Special variables .DEFAULT_GOAL := libraries From 0c9362f1e51b75cf51e5da0ed46f4dbd97f5fb3f Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 19 May 2019 17:38:05 -0300 Subject: [PATCH 038/153] Move system call lists functionality to make/ This is specific to liblinux. It belongs in the project specifics directory. --- .make/all_targets | 5 ---- .make/targets/all_phony | 1 - .make/targets/phony/system_calls | 11 ------- .make/targets/system_calls/available | 8 ----- .make/targets/system_calls/implemented | 8 ----- .make/targets/system_calls/missing | 6 ---- make/file | 1 + make/system_call_lists | 41 ++++++++++++++++++++++++++ 8 files changed, 42 insertions(+), 39 deletions(-) delete mode 100644 .make/targets/phony/system_calls delete mode 100644 .make/targets/system_calls/available delete mode 100644 .make/targets/system_calls/implemented delete mode 100644 .make/targets/system_calls/missing create mode 100644 make/file create mode 100644 make/system_call_lists diff --git a/.make/all_targets b/.make/all_targets index 29909c0..d1477fe 100644 --- a/.make/all_targets +++ b/.make/all_targets @@ -17,10 +17,5 @@ include .make/targets/examples # Targets for dependency data include .make/targets/dependencies -# System call lists -include .make/targets/system_calls/available -include .make/targets/system_calls/implemented -include .make/targets/system_calls/missing - # Phony targets include .make/targets/all_phony diff --git a/.make/targets/all_phony b/.make/targets/all_phony index 763bcf1..4780f04 100644 --- a/.make/targets/all_phony +++ b/.make/targets/all_phony @@ -29,4 +29,3 @@ clean: rm -rf $(build_directory)/ include .make/targets/phony/examples -include .make/targets/phony/system_calls diff --git a/.make/targets/phony/system_calls b/.make/targets/phony/system_calls deleted file mode 100644 index d02dfcd..0000000 --- a/.make/targets/phony/system_calls +++ /dev/null @@ -1,11 +0,0 @@ -system_call_lists := $(notdir $(wildcard make/targets/system_calls/*)) - -define generate_system_call_list_rule -phony_targets += system-calls.$(1) -system-calls.$(1) : $$(system-calls.$(1)) - cat $$< -endef - -$(foreach list,$(system_call_lists),$(eval $(call generate_system_call_list_rule,$(list)))) - -undefine generate_system_call_list_rule diff --git a/.make/targets/system_calls/available b/.make/targets/system_calls/available deleted file mode 100644 index c5867ec..0000000 --- a/.make/targets/system_calls/available +++ /dev/null @@ -1,8 +0,0 @@ -system-calls.available.sh := $(scripts_directory)/system-calls.available.sh -system-calls.available := $(build_scripts_directory)/system-calls.available - -definitions.h := $(include_liblinux_directory)/definitions.h - -$(system-calls.available) : $(system-calls.available.sh) $(definitions.h) - $(call ensure_target_directory_exists) - $(call gcc.list_defined_macros,$(definitions.h)) | $< > $@ diff --git a/.make/targets/system_calls/implemented b/.make/targets/system_calls/implemented deleted file mode 100644 index b409de3..0000000 --- a/.make/targets/system_calls/implemented +++ /dev/null @@ -1,8 +0,0 @@ -system-calls.implemented.sh := $(scripts_directory)/system-calls.implemented.sh -system-calls.implemented := $(build_scripts_directory)/system-calls.implemented - -liblinux_system_calls := $(basename $(notdir $(wildcard $(include_liblinux_directory)/system_calls/*.h))) - -$(system-calls.implemented) : $(system-calls.implemented.sh) - $(call ensure_target_directory_exists) - $< $(liblinux_system_calls) > $@ diff --git a/.make/targets/system_calls/missing b/.make/targets/system_calls/missing deleted file mode 100644 index 5abb604..0000000 --- a/.make/targets/system_calls/missing +++ /dev/null @@ -1,6 +0,0 @@ -system-calls.missing.sh := $(scripts_directory)/system-calls.missing.sh -system-calls.missing := $(build_scripts_directory)/system-calls.missing - -$(system-calls.missing) : $(system-calls.missing.sh) $(system-calls.available) $(system-calls.implemented) - $(call ensure_target_directory_exists) - $< $(system-calls.available) $(system-calls.implemented) > $@ diff --git a/make/file b/make/file new file mode 100644 index 0000000..bffb160 --- /dev/null +++ b/make/file @@ -0,0 +1 @@ +include make/system_call_lists diff --git a/make/system_call_lists b/make/system_call_lists new file mode 100644 index 0000000..24f6aa6 --- /dev/null +++ b/make/system_call_lists @@ -0,0 +1,41 @@ +# System calls available on the system + +system-calls.available.sh := $(scripts_directory)/system-calls.available.sh +system-calls.available := $(build_scripts_directory)/system-calls.available + +definitions.h := $(include_liblinux_directory)/definitions.h + +$(system-calls.available) : $(system-calls.available.sh) $(definitions.h) + $(call ensure_target_directory_exists) + $(call gcc.list_defined_macros,$(definitions.h)) | $< > $@ + +# System calls implemented in liblinux + +system-calls.implemented.sh := $(scripts_directory)/system-calls.implemented.sh +system-calls.implemented := $(build_scripts_directory)/system-calls.implemented + +liblinux_system_calls := $(basename $(notdir $(wildcard $(include_liblinux_directory)/system_calls/*.h))) + +$(system-calls.implemented) : $(system-calls.implemented.sh) + $(call ensure_target_directory_exists) + $< $(liblinux_system_calls) > $@ + +# System calls missing from liblinux + +system-calls.missing.sh := $(scripts_directory)/system-calls.missing.sh +system-calls.missing := $(build_scripts_directory)/system-calls.missing + +$(system-calls.missing) : $(system-calls.missing.sh) $(system-calls.available) $(system-calls.implemented) + $(call ensure_target_directory_exists) + $< $(system-calls.available) $(system-calls.implemented) > $@ + +# Phony targets + +define system_call_list_rule_template +phony_targets += system-calls.$(1) + +system-calls.$(1) : $$(system-calls.$(1)) + cat $$< +endef + +$(foreach list,available implemented missing,$(eval $(call system_call_list_rule_template,$(list)))) From 83101fa1454a70feb10b7ef61b560dc1da41ba27 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 19 May 2019 18:08:57 -0300 Subject: [PATCH 039/153] Move GCC wrapper and specs functionality to make/ This is specific to liblinux. It belongs in the project specifics directory. Moving the example target generation code to make/examples is necessary because otherwise the build system will attempt to generate targets that depend on the GCC wrapper and specs file before they have been defined. --- .make/all_targets | 3 --- .make/targets/examples | 3 --- make/examples | 2 ++ make/file | 6 ++++++ {.make/targets => make}/gcc_wrapper | 0 5 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 make/examples rename {.make/targets => make}/gcc_wrapper (100%) diff --git a/.make/all_targets b/.make/all_targets index d1477fe..788d3f6 100644 --- a/.make/all_targets +++ b/.make/all_targets @@ -8,9 +8,6 @@ include .make/targets/dynamic_library # Targets for the liblinux process startup files include .make/targets/start -# GCC wrapper script and the specs file used by it -include .make/targets/gcc_wrapper - # Targets for library usage examples include .make/targets/examples diff --git a/.make/targets/examples b/.make/targets/examples index 464f6ea..0558e27 100644 --- a/.make/targets/examples +++ b/.make/targets/examples @@ -43,9 +43,6 @@ $(call generate_static_example_rule,$(1)) $(call generate_dynamic_example_rule,$(1)) endef -# Generate example executable rules for every example source file -$(foreach example,$(sources_examples),$(eval $(call generate_example_rules,$(example)))) - # Compute list of all example targets examples_targets += $(examples_static_targets) $(examples_dynamic_targets) targets += $(examples_targets) diff --git a/make/examples b/make/examples new file mode 100644 index 0000000..d0e7937 --- /dev/null +++ b/make/examples @@ -0,0 +1,2 @@ +# Generate example executable rules for every example source file +$(foreach example,$(sources_examples),$(eval $(call generate_example_rules,$(example)))) diff --git a/make/file b/make/file index bffb160..fb32b44 100644 --- a/make/file +++ b/make/file @@ -1 +1,7 @@ +# The liblinux-gcc wrapper script and liblinux.specs file +include make/gcc_wrapper + +# Generate targets for the library usage examples +include make/examples + include make/system_call_lists diff --git a/.make/targets/gcc_wrapper b/make/gcc_wrapper similarity index 100% rename from .make/targets/gcc_wrapper rename to make/gcc_wrapper From 895b6f8e31dbcbb0748d5ec5077aaf446ed8d86e Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 02:43:37 -0300 Subject: [PATCH 040/153] Define the rule_template make function This template captures the form of all generated rules. They all ensure the existence of their target's directory. Dependencies are optional. If not given any as argument, the dependencies list of the generated rule will be empty. --- .make/all_targets | 3 +++ .make/targets/template | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 .make/targets/template diff --git a/.make/all_targets b/.make/all_targets index 788d3f6..222ef7e 100644 --- a/.make/all_targets +++ b/.make/all_targets @@ -1,3 +1,6 @@ +# Template that all generated rules follow +include .make/targets/template + # Object files resulting from the compilation of translation units include .make/targets/objects diff --git a/.make/targets/template b/.make/targets/template new file mode 100644 index 0000000..ce7c2bb --- /dev/null +++ b/.make/targets/template @@ -0,0 +1,16 @@ +# Common rule template that all generated rules follow. +# All rules ensure that their target's directory exist. +# +# Arguments: +# $(1) = path to target file +# $(2) = command that generates $(1) +# $(3) = optional dependencies list +# +# Returns: +# generated rule text for the given parameters +# +define rule_template +$(1) : $(3) + $$(call ensure_target_directory_exists) + $(2) +endef From 91f615069cb05c45df76a962db037590344c9bb2 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 02:47:56 -0300 Subject: [PATCH 041/153] Update object_rule_template to use rule_template Avoids repetition. --- .make/targets/objects | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.make/targets/objects b/.make/targets/objects index 147954c..3487cf7 100644 --- a/.make/targets/objects +++ b/.make/targets/objects @@ -16,11 +16,7 @@ # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -define object_rule_template -$(2) : $(1) $(3) - $$(call ensure_target_directory_exists) - $$(call compiler.compile_object,$$@,$$<,$(4)) -endef +object_rule_template = $(call rule_template,$(2),$$(call compiler.compile_object,$$@,$$<,$(4)),$(1) $(3)) # Computes the parameters for and evaluates the object rule template. # From 6e081d15bdf490723fbefae0f67bd4e6ed95eab7 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 02:57:50 -0300 Subject: [PATCH 042/153] Use rule_template for dependency file rules Avoids repetition. --- .make/targets/dependencies | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.make/targets/dependencies b/.make/targets/dependencies index 33cab9e..48c6162 100644 --- a/.make/targets/dependencies +++ b/.make/targets/dependencies @@ -10,9 +10,7 @@ define dependency_file_rule_template dependency_files += $(2) -$(2) : $(1) - $$(call ensure_target_directory_exists) - $$(call compiler.generate_dependency_data,$$@,$$<,$$(call $(3),$$<)) +$(call rule_template,$(2),$$(call compiler.generate_dependency_data,$$@,$$<,$$(call $(3),$$<)),$(1)) endef # Computes the parameters for and evaluates the dependency file rule template. From c03b5fefe58b78ff99512f8e125a82cd36181f70 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 03:12:28 -0300 Subject: [PATCH 043/153] Disable all predefined make rules and variables The build system framework defines all its rules. There is no need for legacy make rules in the make database. --- .make/file | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.make/file b/.make/file index 6469908..ba33015 100644 --- a/.make/file +++ b/.make/file @@ -1,3 +1,6 @@ +# Disable all predefined rules and variables +MAKEFLAGS += --no-builtin-rules --no-builtin-variables + # Boolean logic in make include .make/logic From 2ea58ef03d7c6be0a42b39940b737f02d4c13dda Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 03:15:49 -0300 Subject: [PATCH 044/153] Use rule_template in start_object_rule_template Avoids repetition. --- .make/targets/start | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.make/targets/start b/.make/targets/start index c490486..d8cf864 100644 --- a/.make/targets/start +++ b/.make/targets/start @@ -9,9 +9,7 @@ # $(2) = path to start object file # define start_object_rule_template -$(2) : $(1) $(3) - $$(call ensure_target_directory_exists) - $$(call compiler.compile_startup_object,$$@,$$<) +$(call rule_template,$(2),$$(call compiler.compile_startup_object,$$@,$$<),$(1) $(3)) endef # Computes the parameters for and evaluates the start object rule template. From 58f547cb6b063bf158a7769e155e4df2024c1c7f Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 03:19:39 -0300 Subject: [PATCH 045/153] Move .make/targets/start to make/start Process startup files are specific to liblinux. Rules for building these files belong in the make/ directory. --- .make/all_targets | 3 --- make/file | 3 +++ {.make/targets => make}/start | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename {.make/targets => make}/start (100%) diff --git a/.make/all_targets b/.make/all_targets index 222ef7e..6e5db7b 100644 --- a/.make/all_targets +++ b/.make/all_targets @@ -8,9 +8,6 @@ include .make/targets/objects include .make/targets/static_library include .make/targets/dynamic_library -# Targets for the liblinux process startup files -include .make/targets/start - # Targets for library usage examples include .make/targets/examples diff --git a/make/file b/make/file index fb32b44..9fdf386 100644 --- a/make/file +++ b/make/file @@ -1,3 +1,6 @@ +# Targets for the liblinux process startup files +include make/start + # The liblinux-gcc wrapper script and liblinux.specs file include make/gcc_wrapper diff --git a/.make/targets/start b/make/start similarity index 100% rename from .make/targets/start rename to make/start From 6d727e7282aee97e6cac4da4eb8888892b308ac2 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 03:27:02 -0300 Subject: [PATCH 046/153] Move object file rule evaluation to make/objects The rule evaluation phase depends on project-specific variables. It belongs on the make/ directory. --- .make/targets/objects | 2 -- make/file | 3 +++ make/objects | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 make/objects diff --git a/.make/targets/objects b/.make/targets/objects index 3487cf7..46ad112 100644 --- a/.make/targets/objects +++ b/.make/targets/objects @@ -39,5 +39,3 @@ $(call generate_static_object_rule,$(1)) $(call generate_dynamic_object_rule,$(1)) endef -# Generate object file rules for every source file -$(foreach source,$(sources_library),$(eval $(call generate_object_rules,$(source)))) diff --git a/make/file b/make/file index 9fdf386..1090ff4 100644 --- a/make/file +++ b/make/file @@ -1,3 +1,6 @@ +# Object files resulting from the compilation of translation units +include make/objects + # Targets for the liblinux process startup files include make/start diff --git a/make/objects b/make/objects new file mode 100644 index 0000000..0a0aadc --- /dev/null +++ b/make/objects @@ -0,0 +1,2 @@ +# Generate object file rules for every source file +$(foreach source,$(sources_library),$(eval $(call generate_object_rules,$(source)))) From 0b7afded36fe1c00923f4c20e3939d21010f8a2b Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 03:30:23 -0300 Subject: [PATCH 047/153] Remove useless comment --- .make/targets/objects | 2 -- 1 file changed, 2 deletions(-) diff --git a/.make/targets/objects b/.make/targets/objects index 46ad112..a8d81d2 100644 --- a/.make/targets/objects +++ b/.make/targets/objects @@ -1,5 +1,3 @@ -# Automatic build rule generation for object files - # Rule template for object files. # # The reason why objects depend on their dependency data file From 8c51bcbdabb27946743db996ff55250d225df6b9 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 03:33:46 -0300 Subject: [PATCH 048/153] Improve description of dependency file rules Fixes grammar and a broken reference to a file. --- .make/targets/examples | 6 +++--- .make/targets/objects | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.make/targets/examples b/.make/targets/examples index 0558e27..7d8974d 100644 --- a/.make/targets/examples +++ b/.make/targets/examples @@ -1,9 +1,9 @@ # Rule template for example executables. # # The reason why the executables depend on their dependency data file -# is to trigger the generation of dependency data when it is updated. -# Once generated, future executions of make will benefit from the dependency data. -# Dependency data file generation rules are defined in make/targets/dependencies. +# is to trigger the generation of their dependency data when they are updated. +# Once generated, future executions of make will include and benefit from the dependency data. +# Dependency data file generation rules are defined in .make/targets/dependencies. # # $(1) = path to source file # $(2) = path to executable file diff --git a/.make/targets/objects b/.make/targets/objects index a8d81d2..8229f37 100644 --- a/.make/targets/objects +++ b/.make/targets/objects @@ -1,9 +1,9 @@ # Rule template for object files. # # The reason why objects depend on their dependency data file -# is to trigger the generation of dependency data when it is updated. -# Once generated, future executions of make will benefit from the dependency data. -# Dependency data file generation rules are defined in make/targets/dependencies. +# is to trigger the generation of their dependency data when they are updated. +# Once generated, future executions of make will include and benefit from the dependency data. +# Dependency data file generation rules are defined in .make/targets/dependencies. # # $(1) = path to source file # $(2) = path to object file From cf205a9a5405b7bcb504ad0a50d76acf0b5170e8 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 04:14:07 -0300 Subject: [PATCH 049/153] Evaluate dependency file rules in make/objects The evaluation phase depends on a project-specific variable. It belongs in the make/ directory. --- .make/targets/dependencies | 3 +-- make/objects | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.make/targets/dependencies b/.make/targets/dependencies index 48c6162..12f6dde 100644 --- a/.make/targets/dependencies +++ b/.make/targets/dependencies @@ -21,8 +21,7 @@ endef # generate_dependency_file_rule = $(call dependency_file_rule_template,$(1),$(call source_to_dependency,$(1)),$(2)) -# Generate dependency file rules for library sources, process startup code and examples. -$(foreach file,$(sources_library),$(eval $(call generate_dependency_file_rule,$(file),source_to_objects))) +# Generate dependency file rules for process startup code and examples. $(foreach file,$(sources_start),$(eval $(call generate_dependency_file_rule,$(file),source_to_start_object))) $(foreach file,$(sources_examples),$(eval $(call generate_dependency_file_rule,$(file),example_to_executables))) diff --git a/make/objects b/make/objects index 0a0aadc..1742578 100644 --- a/make/objects +++ b/make/objects @@ -1,2 +1,2 @@ -# Generate object file rules for every source file -$(foreach source,$(sources_library),$(eval $(call generate_object_rules,$(source)))) +# Generate rules for object files and their dependency files +$(foreach source,$(sources_library),$(eval $(call generate_object_rules,$(source)) $(eval $(call generate_dependency_file_rule,$(source),source_to_objects)))) From 77d16f3fefd87f4c16746545da412037afb2311f Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 04:18:19 -0300 Subject: [PATCH 050/153] Evaluate dependency file rules in make/examples The evaluation phase depends on a project-specific variable. It belongs in the make/ directory. --- .make/targets/dependencies | 3 +-- make/examples | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.make/targets/dependencies b/.make/targets/dependencies index 12f6dde..d508b3e 100644 --- a/.make/targets/dependencies +++ b/.make/targets/dependencies @@ -21,9 +21,8 @@ endef # generate_dependency_file_rule = $(call dependency_file_rule_template,$(1),$(call source_to_dependency,$(1)),$(2)) -# Generate dependency file rules for process startup code and examples. +# Generate dependency file rules for process startup code. $(foreach file,$(sources_start),$(eval $(call generate_dependency_file_rule,$(file),source_to_start_object))) -$(foreach file,$(sources_examples),$(eval $(call generate_dependency_file_rule,$(file),example_to_executables))) targets += $(dependency_files) diff --git a/make/examples b/make/examples index d0e7937..f5c3445 100644 --- a/make/examples +++ b/make/examples @@ -1,2 +1,2 @@ # Generate example executable rules for every example source file -$(foreach example,$(sources_examples),$(eval $(call generate_example_rules,$(example)))) +$(foreach example,$(sources_examples),$(eval $(call generate_example_rules,$(example))) $(eval $(call generate_dependency_file_rule,$(example),example_to_executables))) From cb2dc305c379ac1d30be7694e162377a3b792bab Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 04:21:49 -0300 Subject: [PATCH 051/153] Evaluate dependency file rules in make/start The evaluation phase depends on a project-specific variable. It belongs in the make/ directory. --- .make/targets/dependencies | 3 --- make/start | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.make/targets/dependencies b/.make/targets/dependencies index d508b3e..4151dc0 100644 --- a/.make/targets/dependencies +++ b/.make/targets/dependencies @@ -21,9 +21,6 @@ endef # generate_dependency_file_rule = $(call dependency_file_rule_template,$(1),$(call source_to_dependency,$(1)),$(2)) -# Generate dependency file rules for process startup code. -$(foreach file,$(sources_start),$(eval $(call generate_dependency_file_rule,$(file),source_to_start_object))) - targets += $(dependency_files) # The wildcard function returns existing files that match its parameters. diff --git a/make/start b/make/start index d8cf864..114b49a 100644 --- a/make/start +++ b/make/start @@ -19,4 +19,4 @@ endef generate_start_object_rule = $(call start_object_rule_template,$(1),$(call source_to_start_object,$(1)),$(call source_to_dependency,$(1))) # Generate start object rules for all start code files -$(foreach file,$(sources_start),$(eval $(call generate_start_object_rule,$(file)))) +$(foreach file,$(sources_start),$(eval $(call generate_start_object_rule,$(file))) $(eval $(call generate_dependency_file_rule,$(file),source_to_start_object))) From ffe9852a101d1a0de1155b04b27c3031b3ebf5d7 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 04:27:10 -0300 Subject: [PATCH 052/153] Include dependency files in .make/dependencies This should only be done after the user's makefiles have been included. --- .make/dependencies | 14 ++++++++++++++ .make/file | 3 +++ .make/targets/dependencies | 15 --------------- 3 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 .make/dependencies diff --git a/.make/dependencies b/.make/dependencies new file mode 100644 index 0000000..4ecaff0 --- /dev/null +++ b/.make/dependencies @@ -0,0 +1,14 @@ +# The wildcard function returns existing files that match its parameters. +# This prevents make from including files that don't exist. +# +# Make tries to rebuild included files, without the wildcard function +# the dependency data files would be generated with every invocation of make, +# even make clean. +# +# References: +# +# https://www.gnu.org/software/make/manual/html_node/Remaking-Makefiles.html +# https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#include +# https://make.mad-scientist.net/constructed-include-files/ +# +include $(wildcard $(dependency_files)) diff --git a/.make/file b/.make/file index ba33015..e85b5c1 100644 --- a/.make/file +++ b/.make/file @@ -23,6 +23,9 @@ include .make/all_targets # Include the user's makefile, if it exists include $(wildcard make/file) +# Include all generated dependency files +include .make/dependencies + # Special variables .DEFAULT_GOAL := libraries diff --git a/.make/targets/dependencies b/.make/targets/dependencies index 4151dc0..fa4c264 100644 --- a/.make/targets/dependencies +++ b/.make/targets/dependencies @@ -22,18 +22,3 @@ endef generate_dependency_file_rule = $(call dependency_file_rule_template,$(1),$(call source_to_dependency,$(1)),$(2)) targets += $(dependency_files) - -# The wildcard function returns existing files that match its parameters. -# This prevents make from including files that don't exist. -# -# Make tries to rebuild included files, without the wildcard function -# the dependency data files would be generated with every invocation of make, -# even make clean. -# -# References: -# -# https://www.gnu.org/software/make/manual/html_node/Remaking-Makefiles.html -# https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#include -# https://make.mad-scientist.net/constructed-include-files/ -# -include $(wildcard $(dependency_files)) From deda82bc40164d283b6246508812a433e5e2e01b Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 04:42:43 -0300 Subject: [PATCH 053/153] Move rule templates to .make/rules These makefiles don't really generate rules for any targets, they just provide functions to allow the user to generate them. --- .make/all_targets | 12 ------------ .make/file | 3 +++ .make/{targets => rules}/dependencies | 2 -- .make/{targets => rules}/examples | 0 .make/{targets => rules}/objects | 0 .make/{targets => rules}/template | 0 6 files changed, 3 insertions(+), 14 deletions(-) rename .make/{targets => rules}/dependencies (95%) rename .make/{targets => rules}/examples (100%) rename .make/{targets => rules}/objects (100%) rename .make/{targets => rules}/template (100%) diff --git a/.make/all_targets b/.make/all_targets index 6e5db7b..96eede4 100644 --- a/.make/all_targets +++ b/.make/all_targets @@ -1,18 +1,6 @@ -# Template that all generated rules follow -include .make/targets/template - -# Object files resulting from the compilation of translation units -include .make/targets/objects - # The main build targets are the static and dynamic libraries include .make/targets/static_library include .make/targets/dynamic_library -# Targets for library usage examples -include .make/targets/examples - -# Targets for dependency data -include .make/targets/dependencies - # Phony targets include .make/targets/all_phony diff --git a/.make/file b/.make/file index e85b5c1..45e6ee5 100644 --- a/.make/file +++ b/.make/file @@ -17,6 +17,9 @@ include .make/structure include .make/compiler include .make/archiver +# Rule templates +include $(addprefix .make/rules/,template objects dependencies examples) + # List of targets include .make/all_targets diff --git a/.make/targets/dependencies b/.make/rules/dependencies similarity index 95% rename from .make/targets/dependencies rename to .make/rules/dependencies index fa4c264..6d5557d 100644 --- a/.make/targets/dependencies +++ b/.make/rules/dependencies @@ -1,5 +1,3 @@ -# Build rules for dependency files - # Rule template for dependency data files. # # $(1) = path to source file diff --git a/.make/targets/examples b/.make/rules/examples similarity index 100% rename from .make/targets/examples rename to .make/rules/examples diff --git a/.make/targets/objects b/.make/rules/objects similarity index 100% rename from .make/targets/objects rename to .make/rules/objects diff --git a/.make/targets/template b/.make/rules/template similarity index 100% rename from .make/targets/template rename to .make/rules/template From 66c04178e6460dc85fb97cb615b98fbd2f37bf81 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 04:54:47 -0300 Subject: [PATCH 054/153] Define phony targets in .make/phony This should only be done after the user's makefiles have been included so that phony targets defined by the user are taken into account. Fixes a bug caused by empty examples_$(linkage_type)_targets variables. The example rule evaluation code was moved to make/examples which was included after .make/targets/all_phony. The variables were not set at the time the phony targets for examples were being defined and so they ended up depending on nothing. --- .make/all_targets | 3 --- .make/file | 4 +++- .make/{targets/all_phony => phony} | 2 ++ 3 files changed, 5 insertions(+), 4 deletions(-) rename .make/{targets/all_phony => phony} (96%) diff --git a/.make/all_targets b/.make/all_targets index 96eede4..a8f8515 100644 --- a/.make/all_targets +++ b/.make/all_targets @@ -1,6 +1,3 @@ # The main build targets are the static and dynamic libraries include .make/targets/static_library include .make/targets/dynamic_library - -# Phony targets -include .make/targets/all_phony diff --git a/.make/file b/.make/file index 45e6ee5..050f231 100644 --- a/.make/file +++ b/.make/file @@ -29,7 +29,9 @@ include $(wildcard make/file) # Include all generated dependency files include .make/dependencies +# Additional phony targets and .PHONY variable +include .make/phony + # Special variables .DEFAULT_GOAL := libraries -.PHONY: $(phony_targets) diff --git a/.make/targets/all_phony b/.make/phony similarity index 96% rename from .make/targets/all_phony rename to .make/phony index 4780f04..cc8006d 100644 --- a/.make/targets/all_phony +++ b/.make/phony @@ -29,3 +29,5 @@ clean: rm -rf $(build_directory)/ include .make/targets/phony/examples + +.PHONY: $(phony_targets) From 60b45e997fa8954b5ca01e1d8a00d44b71d65678 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:13:38 -0300 Subject: [PATCH 055/153] Move script directory variables to make/structure The make/structure file is for project-specific file system structure. --- GNUmakefile | 4 ---- make/file | 3 +++ make/structure | 2 ++ 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 make/structure diff --git a/GNUmakefile b/GNUmakefile index bd83c94..c8f5aa8 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -39,14 +39,10 @@ sources_examples = $(call glob,$(examples_directory)/*.c) examples = $(basename $(notdir $(sources_examples))) # GCC linker specification file and wrapper script -scripts_directory := scripts - gcc_specs_script := $(scripts_directory)/$(project).specs.sh gcc_wrapper_script := $(scripts_directory)/$(project)-gcc.sh # Linux kernel checkpatch script integration -scripts_linux_directory := $(scripts_directory)/linux - checkpatch.pl := $(scripts_linux_directory)/checkpatch.pl checkpatch_data_files := $(addprefix $(dir $(checkpatch.pl)),const_structs.checkpatch spelling.txt) diff --git a/make/file b/make/file index 1090ff4..8defb23 100644 --- a/make/file +++ b/make/file @@ -1,3 +1,6 @@ +# Project file system structure +include make/structure + # Object files resulting from the compilation of translation units include make/objects diff --git a/make/structure b/make/structure new file mode 100644 index 0000000..6ef6af3 --- /dev/null +++ b/make/structure @@ -0,0 +1,2 @@ +scripts_directory := scripts +scripts_linux_directory := $(scripts_directory)/linux From 5a78767ac8426c2ede22afa7f0bc64c733c0d7bf Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:14:54 -0300 Subject: [PATCH 056/153] Move checkpatch functionality to make/checkpatch Now that project-specific phony targets are properly handled, it's possible to move this feature to the make/checkpatch file. --- GNUmakefile | 20 -------------------- make/checkpatch | 18 ++++++++++++++++++ make/file | 3 +++ 3 files changed, 21 insertions(+), 20 deletions(-) create mode 100644 make/checkpatch diff --git a/GNUmakefile b/GNUmakefile index c8f5aa8..f2bf411 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -42,24 +42,4 @@ examples = $(basename $(notdir $(sources_examples))) gcc_specs_script := $(scripts_directory)/$(project).specs.sh gcc_wrapper_script := $(scripts_directory)/$(project)-gcc.sh -# Linux kernel checkpatch script integration -checkpatch.pl := $(scripts_linux_directory)/checkpatch.pl -checkpatch_data_files := $(addprefix $(dir $(checkpatch.pl)),const_structs.checkpatch spelling.txt) - -linux_script_url = https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/scripts/$(1) -download_linux_script = $(call download,$(call linux_script_url,$(notdir $(1))),$(1)) - -$(checkpatch.pl): $(checkpatch_data_files) - $(call download_linux_script,$@) - chmod +x $@ - -$(checkpatch_data_files): - $(call download_linux_script,$@) - -phony_targets += checkpatch -checkpatch: $(checkpatch.pl) - find $(include_directory) $(source_directory) $(start_directory) $(examples_directory) \ - -type f \ - -exec $(checkpatch.pl) --quiet --no-tree --file {} \; - include .make/file diff --git a/make/checkpatch b/make/checkpatch new file mode 100644 index 0000000..eef0199 --- /dev/null +++ b/make/checkpatch @@ -0,0 +1,18 @@ +checkpatch.pl := $(scripts_linux_directory)/checkpatch.pl +checkpatch_data_files := $(addprefix $(dir $(checkpatch.pl)),const_structs.checkpatch spelling.txt) + +linux_script_url = https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/scripts/$(1) +download_linux_script = $(call download,$(call linux_script_url,$(notdir $(1))),$(1)) + +$(checkpatch.pl): $(checkpatch_data_files) + $(call download_linux_script,$@) + chmod +x $@ + +$(checkpatch_data_files): + $(call download_linux_script,$@) + +phony_targets += checkpatch +checkpatch: $(checkpatch.pl) + find $(include_directory) $(source_directory) $(start_directory) $(examples_directory) \ + -type f \ + -exec $(checkpatch.pl) --quiet --no-tree --file {} \; diff --git a/make/file b/make/file index 8defb23..c915d66 100644 --- a/make/file +++ b/make/file @@ -14,3 +14,6 @@ include make/gcc_wrapper include make/examples include make/system_call_lists + +# Linux kernel checkpatch script integration +include make/checkpatch From ccb2c42bbb33fafab6143882360a995f14b8e41e Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:19:58 -0300 Subject: [PATCH 057/153] Move include directory variables to make/structure Also remove unused headers_library make variable. --- GNUmakefile | 6 ------ make/structure | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index f2bf411..2c81e9c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,12 +3,6 @@ project := lib$(library) architecture := x86_64 C.freestanding := yes -# Library headers -include_directory := include -include_liblinux_directory := $(include_directory)/liblinux - -headers_library = $(call find,$(include_liblinux_directory),file?) - # Library sources and objects source_directory := source source_architecture_directory := $(source_directory)/arch/$(architecture) diff --git a/make/structure b/make/structure index 6ef6af3..c206c62 100644 --- a/make/structure +++ b/make/structure @@ -1,2 +1,5 @@ +include_directory := include +include_liblinux_directory := $(include_directory)/liblinux + scripts_directory := scripts scripts_linux_directory := $(scripts_directory)/linux From 02bcd14a75b4ecb96cc049475677c9d91f3ef56f Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:23:17 -0300 Subject: [PATCH 058/153] Move source directory variables to make/structure --- GNUmakefile | 3 --- make/structure | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 2c81e9c..0e1474d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -4,9 +4,6 @@ architecture := x86_64 C.freestanding := yes # Library sources and objects -source_directory := source -source_architecture_directory := $(source_directory)/arch/$(architecture) - sources_library = $(call find,$(source_directory),file?) objects_static_library = $(call source_to_static_object,$(sources_library)) diff --git a/make/structure b/make/structure index c206c62..7ff3405 100644 --- a/make/structure +++ b/make/structure @@ -1,5 +1,8 @@ include_directory := include include_liblinux_directory := $(include_directory)/liblinux +source_directory := source +source_architecture_directory := $(source_directory)/arch/$(architecture) + scripts_directory := scripts scripts_linux_directory := $(scripts_directory)/linux From 6958ae299231feb0fe4bb6a859ab51e8a908bd32 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:30:57 -0300 Subject: [PATCH 059/153] Move sources_library make variable to make/sources Also include make/sources in the project's makefile. --- GNUmakefile | 4 +--- make/file | 3 +++ make/sources | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 make/sources diff --git a/GNUmakefile b/GNUmakefile index 0e1474d..623e997 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,9 +3,7 @@ project := lib$(library) architecture := x86_64 C.freestanding := yes -# Library sources and objects -sources_library = $(call find,$(source_directory),file?) - +# Library objects objects_static_library = $(call source_to_static_object,$(sources_library)) objects_dynamic_library = $(call source_to_dynamic_object,$(sources_library)) diff --git a/make/file b/make/file index c915d66..fc6bf03 100644 --- a/make/file +++ b/make/file @@ -1,6 +1,9 @@ # Project file system structure include make/structure +# Library sources +include make/sources + # Object files resulting from the compilation of translation units include make/objects diff --git a/make/sources b/make/sources new file mode 100644 index 0000000..f12ef82 --- /dev/null +++ b/make/sources @@ -0,0 +1 @@ +sources_library = $(call find,$(source_directory),file?) From 842e927119d747f54f91ae09f2c80528be771571 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:37:48 -0300 Subject: [PATCH 060/153] Move start directory variables to make/structure --- GNUmakefile | 3 --- make/structure | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 623e997..f7429f5 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -10,9 +10,6 @@ objects_dynamic_library = $(call source_to_dynamic_object,$(sources_library)) objects_libraries = $(objects_static_library) $(objects_dynamic_library) # Process start code -start_directory := start -start_architecture_directory := $(start_directory)/$(architecture) - sources_start = $(call find,$(start_architecture_directory),file?) objects_start = $(call source_to_start_object,$(sources_start)) diff --git a/make/structure b/make/structure index 7ff3405..6f430f8 100644 --- a/make/structure +++ b/make/structure @@ -4,5 +4,8 @@ include_liblinux_directory := $(include_directory)/liblinux source_directory := source source_architecture_directory := $(source_directory)/arch/$(architecture) +start_directory := start +start_architecture_directory := $(start_directory)/$(architecture) + scripts_directory := scripts scripts_linux_directory := $(scripts_directory)/linux From 19a57f27e84c96ffa5f38350ce7254cab2f0ee53 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:42:22 -0300 Subject: [PATCH 061/153] Move examples directory variable to make/structure --- GNUmakefile | 2 -- make/structure | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index f7429f5..517d16a 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -18,8 +18,6 @@ objects_start = $(call source_to_start_object,$(sources_start)) objects = $(objects_libraries) $(objects_start) # Library usage examples -examples_directory := examples - sources_examples = $(call glob,$(examples_directory)/*.c) examples = $(basename $(notdir $(sources_examples))) diff --git a/make/structure b/make/structure index 6f430f8..6f47561 100644 --- a/make/structure +++ b/make/structure @@ -7,5 +7,7 @@ source_architecture_directory := $(source_directory)/arch/$(architecture) start_directory := start start_architecture_directory := $(start_directory)/$(architecture) +examples_directory := examples + scripts_directory := scripts scripts_linux_directory := $(scripts_directory)/linux From 1dca8556f2618883bbeeb488b0ef3dfbab93be3e Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:43:29 -0300 Subject: [PATCH 062/153] Move object list variables to make/objects --- GNUmakefile | 6 ------ make/objects | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 517d16a..8150808 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,12 +3,6 @@ project := lib$(library) architecture := x86_64 C.freestanding := yes -# Library objects -objects_static_library = $(call source_to_static_object,$(sources_library)) -objects_dynamic_library = $(call source_to_dynamic_object,$(sources_library)) - -objects_libraries = $(objects_static_library) $(objects_dynamic_library) - # Process start code sources_start = $(call find,$(start_architecture_directory),file?) diff --git a/make/objects b/make/objects index 1742578..b671bc7 100644 --- a/make/objects +++ b/make/objects @@ -1,2 +1,7 @@ +objects_static_library = $(call source_to_static_object,$(sources_library)) +objects_dynamic_library = $(call source_to_dynamic_object,$(sources_library)) + +objects_libraries = $(objects_static_library) $(objects_dynamic_library) + # Generate rules for object files and their dependency files $(foreach source,$(sources_library),$(eval $(call generate_object_rules,$(source)) $(eval $(call generate_dependency_file_rule,$(source),source_to_objects)))) From 0baad5375c69b9ef82c0a8fdff9b7ebfdb4cafbd Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:45:01 -0300 Subject: [PATCH 063/153] Move sources_start variable to make/sources --- GNUmakefile | 2 -- make/sources | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 8150808..9bea021 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -4,8 +4,6 @@ architecture := x86_64 C.freestanding := yes # Process start code -sources_start = $(call find,$(start_architecture_directory),file?) - objects_start = $(call source_to_start_object,$(sources_start)) # All objects diff --git a/make/sources b/make/sources index f12ef82..ab02ca3 100644 --- a/make/sources +++ b/make/sources @@ -1 +1,2 @@ sources_library = $(call find,$(source_directory),file?) +sources_start = $(call find,$(start_architecture_directory),file?) From 1909675887f3c7925223fdf882be27defa53a9d8 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:45:38 -0300 Subject: [PATCH 064/153] Move sources_examples variable to make/sources --- GNUmakefile | 2 -- make/sources | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 9bea021..bf43167 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -10,8 +10,6 @@ objects_start = $(call source_to_start_object,$(sources_start)) objects = $(objects_libraries) $(objects_start) # Library usage examples -sources_examples = $(call glob,$(examples_directory)/*.c) - examples = $(basename $(notdir $(sources_examples))) # GCC linker specification file and wrapper script diff --git a/make/sources b/make/sources index ab02ca3..86d7b6e 100644 --- a/make/sources +++ b/make/sources @@ -1,2 +1,3 @@ sources_library = $(call find,$(source_directory),file?) sources_start = $(call find,$(start_architecture_directory),file?) +sources_examples = $(call glob,$(examples_directory)/*.c) From 90d470fca600a41e219d21cf71eea7cc1dc4d3a8 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:49:50 -0300 Subject: [PATCH 065/153] Move objects_start variable to make/start --- GNUmakefile | 3 --- make/start | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index bf43167..a4cc84c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,9 +3,6 @@ project := lib$(library) architecture := x86_64 C.freestanding := yes -# Process start code -objects_start = $(call source_to_start_object,$(sources_start)) - # All objects objects = $(objects_libraries) $(objects_start) diff --git a/make/start b/make/start index 114b49a..c34781a 100644 --- a/make/start +++ b/make/start @@ -1,3 +1,5 @@ +objects_start = $(call source_to_start_object,$(sources_start)) + # Build targets for the liblinux process startup objects: # # _start.o From c4e2ffe45064b5c0e5e2a85c4d87ca444d56f2f0 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:51:20 -0300 Subject: [PATCH 066/153] Move objects variable to make/file --- GNUmakefile | 3 --- make/file | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index a4cc84c..b68120f 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,9 +3,6 @@ project := lib$(library) architecture := x86_64 C.freestanding := yes -# All objects -objects = $(objects_libraries) $(objects_start) - # Library usage examples examples = $(basename $(notdir $(sources_examples))) diff --git a/make/file b/make/file index fc6bf03..8ed06b0 100644 --- a/make/file +++ b/make/file @@ -10,6 +10,9 @@ include make/objects # Targets for the liblinux process startup files include make/start +# All objects +objects = $(objects_libraries) $(objects_start) + # The liblinux-gcc wrapper script and liblinux.specs file include make/gcc_wrapper From 52bce85ae6af05221bb557cc83da27a6da876a7a Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:52:49 -0300 Subject: [PATCH 067/153] Move wrapper script variables to make/gcc_wrapper --- GNUmakefile | 4 ---- make/gcc_wrapper | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index b68120f..ea13cc4 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -6,8 +6,4 @@ C.freestanding := yes # Library usage examples examples = $(basename $(notdir $(sources_examples))) -# GCC linker specification file and wrapper script -gcc_specs_script := $(scripts_directory)/$(project).specs.sh -gcc_wrapper_script := $(scripts_directory)/$(project)-gcc.sh - include .make/file diff --git a/make/gcc_wrapper b/make/gcc_wrapper index c51b824..09217e6 100644 --- a/make/gcc_wrapper +++ b/make/gcc_wrapper @@ -1,6 +1,10 @@ # GCC wrapper script and the specs file used by it # Makes building example and application code painless +# GCC linker specification file and wrapper script +gcc_specs_script := $(scripts_directory)/$(project).specs.sh +gcc_wrapper_script := $(scripts_directory)/$(project)-gcc.sh + gcc_wrapper := $(build_scripts_directory)/$(notdir $(basename $(gcc_wrapper_script))) gcc_specs := $(build_libraries_directory)/$(notdir $(basename $(gcc_specs_script))) From 105ee0b354a107687c1277594ada9e966e925ee9 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:54:34 -0300 Subject: [PATCH 068/153] Move examples variable to make/examples --- GNUmakefile | 3 --- make/examples | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index ea13cc4..d35689c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,7 +3,4 @@ project := lib$(library) architecture := x86_64 C.freestanding := yes -# Library usage examples -examples = $(basename $(notdir $(sources_examples))) - include .make/file diff --git a/make/examples b/make/examples index f5c3445..e74eda8 100644 --- a/make/examples +++ b/make/examples @@ -1,2 +1,5 @@ +# Library usage examples +examples = $(basename $(notdir $(sources_examples))) + # Generate example executable rules for every example source file $(foreach example,$(sources_examples),$(eval $(call generate_example_rules,$(example))) $(eval $(call generate_dependency_file_rule,$(example),example_to_executables))) From 8b3a741a8ff48faf82ce314c125fd7514fd7956f Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:55:05 -0300 Subject: [PATCH 069/153] Move project information to make/file --- GNUmakefile | 5 ----- make/file | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index d35689c..4aec272 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,6 +1 @@ -library := linux -project := lib$(library) -architecture := x86_64 -C.freestanding := yes - include .make/file diff --git a/make/file b/make/file index 8ed06b0..7769ab6 100644 --- a/make/file +++ b/make/file @@ -1,3 +1,8 @@ +library := linux +project := lib$(library) +architecture := x86_64 +C.freestanding := yes + # Project file system structure include make/structure From b43cb7a054cc1215d65ca683c9f94b89400b744b Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 05:59:50 -0300 Subject: [PATCH 070/153] Move .DEFAULT_GOAL variable to make/file The default goal is project-specific so this variable belongs in make/. --- .make/file | 4 ---- make/file | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.make/file b/.make/file index 050f231..df6266a 100644 --- a/.make/file +++ b/.make/file @@ -31,7 +31,3 @@ include .make/dependencies # Additional phony targets and .PHONY variable include .make/phony - -# Special variables - -.DEFAULT_GOAL := libraries diff --git a/make/file b/make/file index 7769ab6..6596209 100644 --- a/make/file +++ b/make/file @@ -3,6 +3,8 @@ project := lib$(library) architecture := x86_64 C.freestanding := yes +.DEFAULT_GOAL := libraries + # Project file system structure include make/structure From 062675d336a5ace5005889373c0e297037fe9c78 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 06:04:31 -0300 Subject: [PATCH 071/153] Move static_library variable to make/libraries --- .make/targets/static_library | 2 -- make/file | 3 +++ make/libraries | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 make/libraries diff --git a/.make/targets/static_library b/.make/targets/static_library index 1185125..6349d45 100644 --- a/.make/targets/static_library +++ b/.make/targets/static_library @@ -1,5 +1,3 @@ -static_library := $(build_libraries_directory)/$(project).a - $(static_library) : $(objects_static_library) $(call ensure_target_directory_exists) $(call archiver.create,$@,$^) diff --git a/make/file b/make/file index 6596209..95d6df1 100644 --- a/make/file +++ b/make/file @@ -14,6 +14,9 @@ include make/sources # Object files resulting from the compilation of translation units include make/objects +# Static and dynamic libraries +include make/libraries + # Targets for the liblinux process startup files include make/start diff --git a/make/libraries b/make/libraries new file mode 100644 index 0000000..166ba4f --- /dev/null +++ b/make/libraries @@ -0,0 +1 @@ +static_library := $(build_libraries_directory)/$(project).a From 6c5c2e35145213737310f2ef09b236c225cd24da Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 06:05:18 -0300 Subject: [PATCH 072/153] Move dynamic_library variable to make/libraries --- .make/targets/dynamic_library | 2 -- make/libraries | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.make/targets/dynamic_library b/.make/targets/dynamic_library index 79d9c3c..8282f66 100644 --- a/.make/targets/dynamic_library +++ b/.make/targets/dynamic_library @@ -1,5 +1,3 @@ -dynamic_library := $(build_libraries_directory)/$(project).so - $(dynamic_library) : $(objects_dynamic_library) $(call ensure_target_directory_exists) $(call compiler.compile_dynamic_library,$@,$^) diff --git a/make/libraries b/make/libraries index 166ba4f..bf6240a 100644 --- a/make/libraries +++ b/make/libraries @@ -1 +1,2 @@ static_library := $(build_libraries_directory)/$(project).a +dynamic_library := $(build_libraries_directory)/$(project).so From 32d9b6f428fbeb2bd1d085729b456cfff5e996ad Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 06:45:27 -0300 Subject: [PATCH 073/153] Add static library rule template Generates rules for creating a static library out of object files. --- .make/file | 2 +- .make/rules/libraries | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 .make/rules/libraries diff --git a/.make/file b/.make/file index df6266a..df146a3 100644 --- a/.make/file +++ b/.make/file @@ -18,7 +18,7 @@ include .make/compiler include .make/archiver # Rule templates -include $(addprefix .make/rules/,template objects dependencies examples) +include $(addprefix .make/rules/,template objects libraries dependencies examples) # List of targets include .make/all_targets diff --git a/.make/rules/libraries b/.make/rules/libraries new file mode 100644 index 0000000..b4c9582 --- /dev/null +++ b/.make/rules/libraries @@ -0,0 +1,22 @@ +# Rule template for static libraries. +# +# Arguments: +# $(1) = path to static library +# $(2) = list of object files +# +# Returns: +# rules for generating static library $(1) from the objects in $(2) +# +static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create,$$@,$$^),$(2)) + +# Evaluates a library rule template. +# +# Arguments: +# $(1) = path to static library +# $(2) = list of object files +# $(3) = linkage type +# +# Returns: +# ε +# +evaluate_library_rule = $(eval $(call $(3)_library_rule_template,$(1),$(2))) From c7fca38fc589c8dbbad5f4f3643559347854e428 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 06:51:10 -0300 Subject: [PATCH 074/153] Add dynamic library rule template Generates rules for creating a dynamic library out of object files. --- .make/rules/libraries | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.make/rules/libraries b/.make/rules/libraries index b4c9582..413eb80 100644 --- a/.make/rules/libraries +++ b/.make/rules/libraries @@ -9,6 +9,17 @@ # static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create,$$@,$$^),$(2)) +# Rule template for dynamic libraries. +# +# Arguments: +# $(1) = path to dynamic library +# $(2) = list of object files +# +# Returns: +# rules for generating dynamic library $(1) from the objects in $(2) +# +dynamic_library_rule_template = $(call rule_template,$(1),$$(call compiler.compile_dynamic_library,$$@,$$^),$(2)) + # Evaluates a library rule template. # # Arguments: From 9dfc019520b9dbae80bd4df2062039dc8aa8be94 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 06:55:05 -0300 Subject: [PATCH 075/153] Delete .make/targets/static_library It is no longer needed now that static library rule templates exist. --- .make/all_targets | 2 -- .make/targets/static_library | 5 ----- 2 files changed, 7 deletions(-) delete mode 100644 .make/targets/static_library diff --git a/.make/all_targets b/.make/all_targets index a8f8515..64b15df 100644 --- a/.make/all_targets +++ b/.make/all_targets @@ -1,3 +1 @@ -# The main build targets are the static and dynamic libraries -include .make/targets/static_library include .make/targets/dynamic_library diff --git a/.make/targets/static_library b/.make/targets/static_library deleted file mode 100644 index 6349d45..0000000 --- a/.make/targets/static_library +++ /dev/null @@ -1,5 +0,0 @@ -$(static_library) : $(objects_static_library) - $(call ensure_target_directory_exists) - $(call archiver.create,$@,$^) - -targets += $(static_library) From b3f2a51c41df3a31ceb6b63c287f4aa37f6bae6a Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 06:56:35 -0300 Subject: [PATCH 076/153] Delete .make/targets/dynamic_library It is no longer needed now that static library rule templates exist. --- .make/all_targets | 1 - .make/file | 3 --- .make/targets/dynamic_library | 5 ----- 3 files changed, 9 deletions(-) delete mode 100644 .make/all_targets delete mode 100644 .make/targets/dynamic_library diff --git a/.make/all_targets b/.make/all_targets deleted file mode 100644 index 64b15df..0000000 --- a/.make/all_targets +++ /dev/null @@ -1 +0,0 @@ -include .make/targets/dynamic_library diff --git a/.make/file b/.make/file index df146a3..2df1ee9 100644 --- a/.make/file +++ b/.make/file @@ -20,9 +20,6 @@ include .make/archiver # Rule templates include $(addprefix .make/rules/,template objects libraries dependencies examples) -# List of targets -include .make/all_targets - # Include the user's makefile, if it exists include $(wildcard make/file) diff --git a/.make/targets/dynamic_library b/.make/targets/dynamic_library deleted file mode 100644 index 8282f66..0000000 --- a/.make/targets/dynamic_library +++ /dev/null @@ -1,5 +0,0 @@ -$(dynamic_library) : $(objects_dynamic_library) - $(call ensure_target_directory_exists) - $(call compiler.compile_dynamic_library,$@,$^) - -targets += $(dynamic_library) From c62f9ae5e664dfc5423fb3d4297b30b1fb64484c Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 06:59:53 -0300 Subject: [PATCH 077/153] Define static library rules in make/libraries --- make/libraries | 2 ++ 1 file changed, 2 insertions(+) diff --git a/make/libraries b/make/libraries index bf6240a..91af40d 100644 --- a/make/libraries +++ b/make/libraries @@ -1,2 +1,4 @@ static_library := $(build_libraries_directory)/$(project).a dynamic_library := $(build_libraries_directory)/$(project).so + +$(call evaluate_library_rule,$(static_library),$(objects_static_library),static) From 824c4eed5db5b8a73746316781629430b5f9756c Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 07:00:22 -0300 Subject: [PATCH 078/153] Define dynamic library rules in make/libraries --- make/libraries | 1 + 1 file changed, 1 insertion(+) diff --git a/make/libraries b/make/libraries index 91af40d..4a86580 100644 --- a/make/libraries +++ b/make/libraries @@ -2,3 +2,4 @@ static_library := $(build_libraries_directory)/$(project).a dynamic_library := $(build_libraries_directory)/$(project).so $(call evaluate_library_rule,$(static_library),$(objects_static_library),static) +$(call evaluate_library_rule,$(dynamic_library),$(objects_dynamic_library),dynamic) From 9b80b82a1b96b5e8e653580b9fa8c86cb7a18ff4 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 07:09:30 -0300 Subject: [PATCH 079/153] Define and use function for GCC's include option --- .make/compilers/gcc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index 12b8379..b77f062 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -4,6 +4,7 @@ gcc := gcc # GCC option variable and function definitions gcc_standard_option = -std=$(1) gcc_library_directory_option = -L$(1) +gcc_include_directory_option = -I $(include_directory) gcc_compile_option := -c gcc_preprocess_option := -E gcc_inhibit_linemarkers_option := -P @@ -22,7 +23,7 @@ gcc_dependency_generation_options = -M -MF $(1) $(foreach target,$(2),-MT $(targ # Common GCC options gcc_dialect_options = $(strip $(call gcc_standard_option,$(or $(1),c99)) $(if $(2),-ffreestanding)) gcc_warning_options := -Wall -Wextra -Wpedantic -gcc_preprocessor_options := -I $(include_directory) $(gcc_inhibit_linemarkers_option) +gcc_preprocessor_options := $(call gcc_include_directory_option,$(include_directory)) $(gcc_inhibit_linemarkers_option) gcc_optimization_options := -Os -fno-strict-aliasing gcc_instrumentation_options := -fno-stack-protector From 2469522dd42809ae33206090ac3f174504708460 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 07:10:14 -0300 Subject: [PATCH 080/153] Convert variables to recursively expanded The include_directory variable may not be defined at this time, so the evaluation of the variable must be deferred. --- .make/compiler | 2 +- .make/compilers/gcc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.make/compiler b/.make/compiler index 3ff0bad..efce533 100644 --- a/.make/compiler +++ b/.make/compiler @@ -3,7 +3,7 @@ include .make/compilers/gcc default_compiler := gcc compiler := $(default_compiler) -compiler_common_options := $($(compiler)_common_options) +compiler_common_options = $($(compiler)_common_options) compiler_library_search_options = $($(compiler)_library_directory_option) compiler_code_generation_options = $($(compiler)_code_generation_options) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index b77f062..00c2a8d 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -23,7 +23,7 @@ gcc_dependency_generation_options = -M -MF $(1) $(foreach target,$(2),-MT $(targ # Common GCC options gcc_dialect_options = $(strip $(call gcc_standard_option,$(or $(1),c99)) $(if $(2),-ffreestanding)) gcc_warning_options := -Wall -Wextra -Wpedantic -gcc_preprocessor_options := $(call gcc_include_directory_option,$(include_directory)) $(gcc_inhibit_linemarkers_option) +gcc_preprocessor_options = $(call gcc_include_directory_option,$(include_directory)) $(gcc_inhibit_linemarkers_option) gcc_optimization_options := -Os -fno-strict-aliasing gcc_instrumentation_options := -fno-stack-protector From b6926dbb1b4bbd8b51393ed4663749a92e3f7dde Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 07:19:55 -0300 Subject: [PATCH 081/153] Update description of .make/structure This file doesn't contain the project's file system structure anymore. --- .make/file | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.make/file b/.make/file index 2df1ee9..5569f69 100644 --- a/.make/file +++ b/.make/file @@ -10,7 +10,7 @@ include .make/commands # Make functions available to the entire build system include .make/all_functions -# Project file system structure +# File system structure of the build tree include .make/structure # Compiler and archiver configuration From f8c064956b231b2e643aa666bbb7e07286e6567f Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 07:22:15 -0300 Subject: [PATCH 082/153] Conditionally set the build_directory variable This allows the user to override the build directory. --- .make/structure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.make/structure b/.make/structure index 566a68d..f228dbe 100644 --- a/.make/structure +++ b/.make/structure @@ -1,5 +1,5 @@ # Directories for build artifacts -build_directory := build +build_directory ?= build build_root_directory := $(build_directory)/$(architecture) build_objects_directory := $(build_root_directory)/objects From fb33e1544b6caaf797734376e4e865f655b4d7b9 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 21 May 2019 07:23:21 -0300 Subject: [PATCH 083/153] Recursively expand the build directory variables The variables needed for computing the structure of the build tree have not been defined yet. Their evaluation should be deferred. --- .make/structure | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.make/structure b/.make/structure index f228dbe..a5b2d6a 100644 --- a/.make/structure +++ b/.make/structure @@ -1,21 +1,21 @@ # Directories for build artifacts build_directory ?= build -build_root_directory := $(build_directory)/$(architecture) +build_root_directory = $(build_directory)/$(architecture) -build_objects_directory := $(build_root_directory)/objects -build_objects_static_directory := $(build_objects_directory)/static -build_objects_dynamic_directory := $(build_objects_directory)/dynamic +build_objects_directory = $(build_root_directory)/objects +build_objects_static_directory = $(build_objects_directory)/static +build_objects_dynamic_directory = $(build_objects_directory)/dynamic -build_libraries_directory := $(build_root_directory)/libraries -build_start_directory := $(build_libraries_directory)/$(start_directory) +build_libraries_directory = $(build_root_directory)/libraries +build_start_directory = $(build_libraries_directory)/$(start_directory) -build_examples_directory := $(build_root_directory)/$(examples_directory) -build_examples_static_directory := $(build_examples_directory)/static -build_examples_dynamic_directory := $(build_examples_directory)/dynamic +build_examples_directory = $(build_root_directory)/$(examples_directory) +build_examples_static_directory = $(build_examples_directory)/static +build_examples_dynamic_directory = $(build_examples_directory)/dynamic -build_dependencies_directory := $(build_root_directory)/dependencies +build_dependencies_directory = $(build_root_directory)/dependencies -build_scripts_directory := $(build_root_directory)/$(scripts_directory) +build_scripts_directory = $(build_root_directory)/$(scripts_directory) # If the build directory is a symbolic link to another directory, # ensure the existence of that directory. From b6fac689062d5a815b16f5ff6e7aa7e9de983d7e Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 29 May 2019 09:36:57 -0300 Subject: [PATCH 084/153] Add linkage make variable This variable will control how the program is linked. --- make/file | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/make/file b/make/file index 95d6df1..732d5f5 100644 --- a/make/file +++ b/make/file @@ -1,8 +1,10 @@ library := linux project := lib$(library) -architecture := x86_64 C.freestanding := yes +architecture ?= x86_64 +linkage ?= static + .DEFAULT_GOAL := libraries # Project file system structure From a3a1e2d23c13f0616ac91c53a98cba3b3795f444 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 29 May 2019 09:49:03 -0300 Subject: [PATCH 085/153] Move path conversion function to make/start Startfiles are specific to liblinux. --- .make/functions/path | 6 ------ make/start | 11 +++++++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.make/functions/path b/.make/functions/path index 2748e14..ec8bab0 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -11,12 +11,6 @@ source_to_dynamic_object = $(call source_to_object,$(1),dynamic) source_to_objects = $(call source_to_static_object,$(1)) $(call source_to_dynamic_object,$(1)) -# Converts a path to a process startup source code file to its corresponding start object file path. -# They may be written in assembly or C. -# -# $(1) = path to process startup source file -# -source_to_start_object = $(patsubst $(start_architecture_directory)/%,$(build_start_directory)/%.o,$(basename $(1))) # Converts the path to a source file to the path to its corresponding dependency data file source_to_dependency = $(addprefix $(build_dependencies_directory)/,$(addsuffix .d,$(basename $(1)))) diff --git a/make/start b/make/start index c34781a..3414488 100644 --- a/make/start +++ b/make/start @@ -1,3 +1,14 @@ +# Converts the path to a startfile source to the path of its target. +# May be written in assembly or C. +# +# Arguments: +# $(1) = path to process startup source file +# +# Returns: +# path to the startfile target +# +source_to_start_object = $(patsubst $(start_architecture_directory)/%,$(build_start_directory)/%.o,$(basename $(1))) + objects_start = $(call source_to_start_object,$(sources_start)) # Build targets for the liblinux process startup objects: From 27c7ed42697b0fa3bbde3977a2de404daea20fd2 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 29 May 2019 13:16:39 -0300 Subject: [PATCH 086/153] Define configuration variable The build configuration is an arbitrary set of attributes like target architecture, static/dynamic linkage, debug/release builds, compiler optimizations, etc. The build configuration will replace the architecture directory as the root of the build tree. --- .make/configuration | 1 + .make/file | 3 +++ .make/structure | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .make/configuration diff --git a/.make/configuration b/.make/configuration new file mode 100644 index 0000000..0275bc4 --- /dev/null +++ b/.make/configuration @@ -0,0 +1 @@ +configuration = $(architecture) diff --git a/.make/file b/.make/file index 5569f69..38ab880 100644 --- a/.make/file +++ b/.make/file @@ -10,6 +10,9 @@ include .make/commands # Make functions available to the entire build system include .make/all_functions +# Build configuration +include .make/configuration + # File system structure of the build tree include .make/structure diff --git a/.make/structure b/.make/structure index a5b2d6a..7d2af41 100644 --- a/.make/structure +++ b/.make/structure @@ -1,6 +1,6 @@ # Directories for build artifacts build_directory ?= build -build_root_directory = $(build_directory)/$(architecture) +build_root_directory = $(build_directory)/$(configuration) build_objects_directory = $(build_root_directory)/objects build_objects_static_directory = $(build_objects_directory)/static From 0aad43baf019b85c0f3b4e65c0f8de758ff1c664 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 29 May 2019 13:47:42 -0300 Subject: [PATCH 087/153] Add make function for computing library file names Generates file names for static and dynamic libraries when given symbolic names. --- .make/all_functions | 1 + .make/functions/library | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 .make/functions/library diff --git a/.make/all_functions b/.make/all_functions index e81c946..141361b 100644 --- a/.make/all_functions +++ b/.make/all_functions @@ -1,6 +1,7 @@ include .make/functions/comparison include .make/functions/directory include .make/functions/file_system +include .make/functions/library include .make/functions/path include .make/functions/recursion include .make/functions/shell diff --git a/.make/functions/library b/.make/functions/library new file mode 100644 index 0000000..18e545d --- /dev/null +++ b/.make/functions/library @@ -0,0 +1,14 @@ +library.prefix := lib +library.extension.static := .a +library.extension.dynamic := .so + +# Computes the file name for the given library name and type. +# +# Arguments: +# $(1) = library name +# $(2) = linkage type: static | dynamic +# +# Returns: +# the file name for the $(1) library +# +library.file_name = $(addsuffix $(library.extension.$(2)),$(addprefix $(library.prefix),$(1))) From 3ccbf30ed91021ada410b3b61e062aee9b34bc82 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Wed, 29 May 2019 14:27:17 -0300 Subject: [PATCH 088/153] Switch to configuration-based builds Gets rid of the messy static/dynamic variables and functions. The build tree is now rooted on the build configuration which consists of target architecture and linkage type. The build system will now configure itself for a static or dynamic build instead of building both at the same time. linkage=static make # Builds statically linked targets linkage=dynamic make # Builds dynamically linked targets This simplifies the build tree and the build system code and allows more configurations to be added in the future. --- .make/configuration | 2 +- .make/functions/path | 34 ++++++++++++++++------------------ .make/phony | 20 ++++---------------- .make/rules/dependencies | 2 +- .make/rules/examples | 25 ++++--------------------- .make/rules/libraries | 10 ++++++---- .make/rules/objects | 20 ++------------------ .make/structure | 4 ---- .make/targets/phony/examples | 13 +++++-------- make/examples | 2 +- make/file | 6 +++--- make/libraries | 6 ++---- make/objects | 7 ++----- make/start | 2 +- 14 files changed, 48 insertions(+), 105 deletions(-) diff --git a/.make/configuration b/.make/configuration index 0275bc4..d184582 100644 --- a/.make/configuration +++ b/.make/configuration @@ -1 +1 @@ -configuration = $(architecture) +configuration = $(architecture)-$(linkage) diff --git a/.make/functions/path b/.make/functions/path index ec8bab0..ca16028 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -1,29 +1,27 @@ # Converts a source file path to its corresponding object file path. -# Parameterized on the linkage type: static or dynamic. # # $(1) = path to source file -# $(2) = linkage type: static | dynamic # -source_to_object = $(patsubst $(source_directory)/%.c,$(build_objects_$(2)_directory)/%.o,$(1)) - -source_to_static_object = $(call source_to_object,$(1),static) -source_to_dynamic_object = $(call source_to_object,$(1),dynamic) - -source_to_objects = $(call source_to_static_object,$(1)) $(call source_to_dynamic_object,$(1)) - +to_object = $(patsubst $(source_directory)/%,$(build_objects_directory)/%.o,$(basename $(1))) # Converts the path to a source file to the path to its corresponding dependency data file -source_to_dependency = $(addprefix $(build_dependencies_directory)/,$(addsuffix .d,$(basename $(1)))) +to_dependency = $(addprefix $(build_dependencies_directory)/,$(addsuffix .d,$(basename $(1)))) + +# Converts a library name to the path to its corresponding library file. +# +# Arguments: +# $(1) = library name +# +# Variables: +# $(linkage) = linkage type: static | dynamic +# +# Returns: +# path to the library target +# +to_library = $(addprefix $(build_libraries_directory)/,$(call library.file_name,$(1),$(linkage))) # Converts an example source file path to its corresponding executable file path. -# Parameterized on the linkage type: static or dynamic. # # $(1) = path to example source file -# $(2) = linkage type: static | dynamic # -example_to_executable = $(patsubst $(examples_directory)/%.c,$(build_examples_$(2)_directory)/%,$(1)) - -example_to_static_executable = $(call example_to_executable,$(1),static) -example_to_dynamic_executable = $(call example_to_executable,$(1),dynamic) - -example_to_executables = $(call example_to_static_executable,$(1)) $(call example_to_dynamic_executable,$(1)) +to_executable = $(patsubst $(examples_directory)/%,$(build_examples_directory)/%,$(basename $(1))) diff --git a/.make/phony b/.make/phony index cc8006d..c87dd23 100644 --- a/.make/phony +++ b/.make/phony @@ -1,28 +1,16 @@ # Phony targets -phony_targets += static-library -static-library: $(static_library) - -phony_targets += dynamic-library -dynamic-library: $(dynamic_library) - -phony_targets += libraries -libraries: static-library dynamic-library +phony_targets += library +library: $(library) phony_targets += startfiles startfiles: $(objects_start) -phony_targets += static-examples -static-examples: $(examples_static_targets) - -phony_targets += dynamic-examples -dynamic-examples: $(examples_dynamic_targets) - phony_targets += examples -examples: static-examples dynamic-examples +examples: $(examples_targets) phony_targets += all -all: libraries startfiles examples +all: library startfiles examples phony_targets += clean clean: diff --git a/.make/rules/dependencies b/.make/rules/dependencies index 6d5557d..b979539 100644 --- a/.make/rules/dependencies +++ b/.make/rules/dependencies @@ -17,6 +17,6 @@ endef # $(2) = make function that converts a path to a source file # to a list of paths to all its targets # -generate_dependency_file_rule = $(call dependency_file_rule_template,$(1),$(call source_to_dependency,$(1)),$(2)) +generate_dependency_file_rule = $(call dependency_file_rule_template,$(1),$(call to_dependency,$(1)),$(2)) targets += $(dependency_files) diff --git a/.make/rules/examples b/.make/rules/examples index 7d8974d..578d693 100644 --- a/.make/rules/examples +++ b/.make/rules/examples @@ -8,41 +8,24 @@ # $(1) = path to source file # $(2) = path to executable file # $(3) = path to dependency data file -# $(4) = linkage type: static | dynamic # # References: # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # define example_rule_template -examples_$(4)_targets += $(2) +examples_targets += $(2) -$(2) : $(1) $(3) $$($(4)_library) $$(objects_start) $$(gcc_wrapper) +$(2) : $(1) $(3) $$(library) $$(objects_start) $$(gcc_wrapper) $$(call ensure_target_directory_exists) - $$(call gcc.compile_example,$$@,$$<,$(4)) + $$(call gcc.compile_example,$$@,$$<,$$(linkage)) endef # Computes the parameters for and evaluates the example rule template. # # $(1) = path to example source file -# $(2) = linkage type: static | dynamic # -generate_example_rule = $(call example_rule_template,$(1),$(call example_to_executable,$(1),$(2)),$(call source_to_dependency,$(1)),$(2)) - -# Rule generators for statically and dynamically linked example executables, -# either individually or both a the same time. -# -# $(1) = path to example source file -# -generate_static_example_rule = $(call generate_example_rule,$(1),static) -generate_dynamic_example_rule = $(call generate_example_rule,$(1),dynamic) - -define generate_example_rules -$(call generate_static_example_rule,$(1)) - -$(call generate_dynamic_example_rule,$(1)) -endef +generate_example_rule = $(call example_rule_template,$(1),$(call to_executable,$(1)),$(call to_dependency,$(1))) # Compute list of all example targets -examples_targets += $(examples_static_targets) $(examples_dynamic_targets) targets += $(examples_targets) diff --git a/.make/rules/libraries b/.make/rules/libraries index 413eb80..b6311f8 100644 --- a/.make/rules/libraries +++ b/.make/rules/libraries @@ -20,14 +20,16 @@ static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create # dynamic_library_rule_template = $(call rule_template,$(1),$$(call compiler.compile_dynamic_library,$$@,$$^),$(2)) -# Evaluates a library rule template. +# Evaluates a library rule template for the current linkage. # # Arguments: -# $(1) = path to static library +# $(1) = library name # $(2) = list of object files -# $(3) = linkage type +# +# Variables: +# $(linkage) = linkage type: static | dynamic # # Returns: # ε # -evaluate_library_rule = $(eval $(call $(3)_library_rule_template,$(1),$(2))) +evaluate_library_rule = $(eval $(call $(linkage)_library_rule_template,$(call to_library,$(1)),$(2))) diff --git a/.make/rules/objects b/.make/rules/objects index 8229f37..8cc7939 100644 --- a/.make/rules/objects +++ b/.make/rules/objects @@ -8,32 +8,16 @@ # $(1) = path to source file # $(2) = path to object file # $(3) = path to dependency data file -# $(4) = linkage type # # References: # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -object_rule_template = $(call rule_template,$(2),$$(call compiler.compile_object,$$@,$$<,$(4)),$(1) $(3)) +object_rule_template = $(call rule_template,$(2),$$(call compiler.compile_object,$$@,$$<,$$(linkage)),$(1) $(3)) # Computes the parameters for and evaluates the object rule template. # # $(1) = path to source file -# $(2) = linkage type # -generate_object_rule = $(call object_rule_template,$(1),$(call source_to_object,$(1),$(2)),$(call source_to_dependency,$(1)),$(2)) - -# Rule generators for statically and dynamically linked objects, -# either individually or both a the same time. -# -# $(1) = path to source file -# -generate_static_object_rule = $(call generate_object_rule,$(1),static) -generate_dynamic_object_rule = $(call generate_object_rule,$(1),dynamic) - -define generate_object_rules -$(call generate_static_object_rule,$(1)) - -$(call generate_dynamic_object_rule,$(1)) -endef +generate_object_rule = $(call object_rule_template,$(1),$(call to_object,$(1)),$(call to_dependency,$(1))) diff --git a/.make/structure b/.make/structure index 7d2af41..1a8c6e5 100644 --- a/.make/structure +++ b/.make/structure @@ -3,15 +3,11 @@ build_directory ?= build build_root_directory = $(build_directory)/$(configuration) build_objects_directory = $(build_root_directory)/objects -build_objects_static_directory = $(build_objects_directory)/static -build_objects_dynamic_directory = $(build_objects_directory)/dynamic build_libraries_directory = $(build_root_directory)/libraries build_start_directory = $(build_libraries_directory)/$(start_directory) build_examples_directory = $(build_root_directory)/$(examples_directory) -build_examples_static_directory = $(build_examples_directory)/static -build_examples_dynamic_directory = $(build_examples_directory)/dynamic build_dependencies_directory = $(build_root_directory)/dependencies diff --git a/.make/targets/phony/examples b/.make/targets/phony/examples index 1a82b3d..f0340fd 100644 --- a/.make/targets/phony/examples +++ b/.make/targets/phony/examples @@ -1,13 +1,10 @@ -define generate_run_example_rule -phony_targets += run-$(1) run-static-$(1) run-dynamic-$(1) - -run-$(1) : run-static-$(1) +configure_dynamic_loader = $(if $(call equal?,$(linkage),dynamic),LD_LIBRARY_PATH=$$(build_libraries_directory)) -run-static-$(1) : $$(build_examples_static_directory)/$(1) - $$(build_examples_static_directory)/$(1) +define generate_run_example_rule +phony_targets += run-$(1) -run-dynamic-$(1) : $$(build_examples_dynamic_directory)/$(1) - LD_LIBRARY_PATH=$$(build_libraries_directory) $$(build_examples_dynamic_directory)/$(1) +run-$(1) : $$(build_examples_directory)/$(1) + $(call configure_dynamic_loader) $$(build_examples_directory)/$(1) endef $(foreach example,$(examples),$(eval $(call generate_run_example_rule,$(example)))) diff --git a/make/examples b/make/examples index e74eda8..5ac454b 100644 --- a/make/examples +++ b/make/examples @@ -2,4 +2,4 @@ examples = $(basename $(notdir $(sources_examples))) # Generate example executable rules for every example source file -$(foreach example,$(sources_examples),$(eval $(call generate_example_rules,$(example))) $(eval $(call generate_dependency_file_rule,$(example),example_to_executables))) +$(foreach example,$(sources_examples),$(eval $(call generate_example_rule,$(example))) $(eval $(call generate_dependency_file_rule,$(example),to_executable))) diff --git a/make/file b/make/file index 732d5f5..378f45d 100644 --- a/make/file +++ b/make/file @@ -1,11 +1,11 @@ -library := linux -project := lib$(library) +library_name := linux +project := lib$(library_name) C.freestanding := yes architecture ?= x86_64 linkage ?= static -.DEFAULT_GOAL := libraries +.DEFAULT_GOAL := library # Project file system structure include make/structure diff --git a/make/libraries b/make/libraries index 4a86580..3f34043 100644 --- a/make/libraries +++ b/make/libraries @@ -1,5 +1,3 @@ -static_library := $(build_libraries_directory)/$(project).a -dynamic_library := $(build_libraries_directory)/$(project).so +library := $(call to_library,$(library_name)) -$(call evaluate_library_rule,$(static_library),$(objects_static_library),static) -$(call evaluate_library_rule,$(dynamic_library),$(objects_dynamic_library),dynamic) +$(call evaluate_library_rule,$(library_name),$(objects_library)) diff --git a/make/objects b/make/objects index b671bc7..5e94e6e 100644 --- a/make/objects +++ b/make/objects @@ -1,7 +1,4 @@ -objects_static_library = $(call source_to_static_object,$(sources_library)) -objects_dynamic_library = $(call source_to_dynamic_object,$(sources_library)) - -objects_libraries = $(objects_static_library) $(objects_dynamic_library) +objects_library = $(call to_object,$(sources_library)) # Generate rules for object files and their dependency files -$(foreach source,$(sources_library),$(eval $(call generate_object_rules,$(source)) $(eval $(call generate_dependency_file_rule,$(source),source_to_objects)))) +$(foreach source,$(sources_library),$(eval $(call generate_object_rule,$(source)) $(eval $(call generate_dependency_file_rule,$(source),to_object)))) diff --git a/make/start b/make/start index 3414488..e95d12d 100644 --- a/make/start +++ b/make/start @@ -29,7 +29,7 @@ endef # # $(1) = path to start code file # -generate_start_object_rule = $(call start_object_rule_template,$(1),$(call source_to_start_object,$(1)),$(call source_to_dependency,$(1))) +generate_start_object_rule = $(call start_object_rule_template,$(1),$(call source_to_start_object,$(1)),$(call to_dependency,$(1))) # Generate start object rules for all start code files $(foreach file,$(sources_start),$(eval $(call generate_start_object_rule,$(file))) $(eval $(call generate_dependency_file_rule,$(file),source_to_start_object))) From f67c96b53405dbb9b6a2fb05afe6cd4701165c01 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 30 May 2019 16:39:45 -0300 Subject: [PATCH 089/153] Fix buggy implementation of the equal? function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make's subst function replaces all occurrences of the string it finds. This causes the equal? function to return an incorrect result when the second string consists of multiple copies of the first: $(call equal?,a,aa) # = $(call equal?,aa,a) # ≠ The correct implementation returns true if both substitutions are empty. Asked about this on Stack Overflow 3 years ago, got an answer by the author of the GNU Make Standard Library and then completely forgot about it until today. References: https://www.gnu.org/software/make/manual/html_node/Text-Functions.html https://stackoverflow.com/q/37469553/512904 https://stackoverflow.com/a/37479819/512904 --- .make/functions/comparison | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.make/functions/comparison b/.make/functions/comparison index 9ae53c2..b94461f 100644 --- a/.make/functions/comparison +++ b/.make/functions/comparison @@ -1,5 +1,5 @@ # x - y = 0 ∴ x = y -equal? = $(if $(subst $(1),,$(2)),,=) +equal? = $(if $(subst $(1),,$(2))$(subst $(2),,$(1)),,=) # x - y ≠ 0 ∴ x ≠ y not_equal? = $(if $(call equal?,$(1),$(2)),,≠) From 8336d590b8f1369c675740728033f7bfa394d8b4 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 30 May 2019 17:10:29 -0300 Subject: [PATCH 090/153] Don't remove the source directory prefix Projects may have multiple source directories. For example: source/ # general source code arch/ # architecture specific code These prefixes should not be handled specially. Better to let them be reflected in the build tree. This results in greater flexibility. --- .make/functions/path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.make/functions/path b/.make/functions/path index ca16028..961cd1e 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -2,7 +2,7 @@ # # $(1) = path to source file # -to_object = $(patsubst $(source_directory)/%,$(build_objects_directory)/%.o,$(basename $(1))) +to_object = $(addprefix $(build_objects_directory)/,$(addsuffix .o,$(basename $(1)))) # Converts the path to a source file to the path to its corresponding dependency data file to_dependency = $(addprefix $(build_dependencies_directory)/,$(addsuffix .d,$(basename $(1)))) From f855a9e19c9a54fdd2f91a6c7c1b749d5d8af3f2 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 30 May 2019 17:15:25 -0300 Subject: [PATCH 091/153] Update documentation of the to_object function Use the new documentation format and document the return value. --- .make/functions/path | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.make/functions/path b/.make/functions/path index 961cd1e..5feb599 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -1,6 +1,10 @@ # Converts a source file path to its corresponding object file path. # -# $(1) = path to source file +# Arguments: +# $(1) = path to source file +# +# Returns: +# path to the object file # to_object = $(addprefix $(build_objects_directory)/,$(addsuffix .o,$(basename $(1)))) From da1257e9bcb1b338e68edc949bc6f9f59aa418f1 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 30 May 2019 17:37:28 -0300 Subject: [PATCH 092/153] Refactor the examples system to be more general Usage examples are simply executables that are linked to a library. The build tree should have an executables directory instead. The directory that contains the executable's source is reflected there and denotes what type of executable it is. Now all the path conversion functions don't use any project-specific structural variables. --- .make/functions/path | 2 +- .make/structure | 2 +- .make/targets/phony/examples | 8 ++++---- make/examples | 3 --- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.make/functions/path b/.make/functions/path index 5feb599..5f50b24 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -28,4 +28,4 @@ to_library = $(addprefix $(build_libraries_directory)/,$(call library.file_name, # # $(1) = path to example source file # -to_executable = $(patsubst $(examples_directory)/%,$(build_examples_directory)/%,$(basename $(1))) +to_executable = $(addprefix $(build_executables_directory)/,$(basename $(1))) diff --git a/.make/structure b/.make/structure index 1a8c6e5..13ae2df 100644 --- a/.make/structure +++ b/.make/structure @@ -7,7 +7,7 @@ build_objects_directory = $(build_root_directory)/objects build_libraries_directory = $(build_root_directory)/libraries build_start_directory = $(build_libraries_directory)/$(start_directory) -build_examples_directory = $(build_root_directory)/$(examples_directory) +build_executables_directory = $(build_root_directory)/executables build_dependencies_directory = $(build_root_directory)/dependencies diff --git a/.make/targets/phony/examples b/.make/targets/phony/examples index f0340fd..7f79e82 100644 --- a/.make/targets/phony/examples +++ b/.make/targets/phony/examples @@ -1,12 +1,12 @@ configure_dynamic_loader = $(if $(call equal?,$(linkage),dynamic),LD_LIBRARY_PATH=$$(build_libraries_directory)) define generate_run_example_rule -phony_targets += run-$(1) +phony_targets += run-$(2) -run-$(1) : $$(build_examples_directory)/$(1) - $(call configure_dynamic_loader) $$(build_examples_directory)/$(1) +run-$(2) : $(1) + $(call configure_dynamic_loader) $(1) endef -$(foreach example,$(examples),$(eval $(call generate_run_example_rule,$(example)))) +$(foreach example,$(sources_examples),$(eval $(call generate_run_example_rule,$(call to_executable,$(example)),$(basename $(example))))) undefine generate_run_example_rule diff --git a/make/examples b/make/examples index 5ac454b..71648f7 100644 --- a/make/examples +++ b/make/examples @@ -1,5 +1,2 @@ -# Library usage examples -examples = $(basename $(notdir $(sources_examples))) - # Generate example executable rules for every example source file $(foreach example,$(sources_examples),$(eval $(call generate_example_rule,$(example))) $(eval $(call generate_dependency_file_rule,$(example),to_executable))) From e8deb27e5dabf52059da9170fa1f6865fd22d829 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 30 May 2019 17:47:23 -0300 Subject: [PATCH 093/153] Update documentation of the to_executable function Use the new documentation format and document the return value. --- .make/functions/path | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.make/functions/path b/.make/functions/path index 5f50b24..07db337 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -26,6 +26,10 @@ to_library = $(addprefix $(build_libraries_directory)/,$(call library.file_name, # Converts an example source file path to its corresponding executable file path. # -# $(1) = path to example source file +# Arguments: +# $(1) = path to executable source file +# +# Returns: +# path to the executable file # to_executable = $(addprefix $(build_executables_directory)/,$(basename $(1))) From 6d6ef42c4b4a289e8f49adbfda2e834e8fc218d9 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 30 May 2019 17:48:53 -0300 Subject: [PATCH 094/153] Document the to_dependency function Describe the function's arguments and return value. --- .make/functions/path | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.make/functions/path b/.make/functions/path index 07db337..54f4401 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -9,6 +9,13 @@ to_object = $(addprefix $(build_objects_directory)/,$(addsuffix .o,$(basename $(1)))) # Converts the path to a source file to the path to its corresponding dependency data file +# +# Arguments: +# $(1) = path to a source file +# +# Returns: +# path to the dependency file +# to_dependency = $(addprefix $(build_dependencies_directory)/,$(addsuffix .d,$(basename $(1)))) # Converts a library name to the path to its corresponding library file. From f5eca78e2df357ab62e8cfad4f660200033568c2 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Fri, 28 Jun 2019 05:36:45 -0300 Subject: [PATCH 095/153] Add library_rule_template make function This function generates the library rules for the current linkage without evaluating them. Useful for building up a set of rules for later evaluation. --- .make/rules/libraries | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.make/rules/libraries b/.make/rules/libraries index b6311f8..60d615a 100644 --- a/.make/rules/libraries +++ b/.make/rules/libraries @@ -20,6 +20,20 @@ static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create # dynamic_library_rule_template = $(call rule_template,$(1),$$(call compiler.compile_dynamic_library,$$@,$$^),$(2)) +# Rule template for libraries corresponding to the current linkage. +# +# Arguments: +# $(1) = library name +# $(2) = list of object files +# +# Variables: +# $(linkage) = linkage type: static | dynamic +# +# Returns: +# rules for generating library $(1) from the objects in $(2) +# +library_rule_template = $(call $(linkage)_library_rule_template,$(call to_library,$(1)),$(2)) + # Evaluates a library rule template for the current linkage. # # Arguments: @@ -32,4 +46,4 @@ dynamic_library_rule_template = $(call rule_template,$(1),$$(call compiler.compi # Returns: # ε # -evaluate_library_rule = $(eval $(call $(linkage)_library_rule_template,$(call to_library,$(1)),$(2))) +evaluate_library_rule = $(eval $(call library_rule_template,$(1),$(2))) From 4bdc5a8a6bc06ca4efa37da52d033963c66da98b Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Fri, 28 Jun 2019 05:56:23 -0300 Subject: [PATCH 096/153] Move run executable rules to .make/rules/run They're still dependent on the liblinux-specific variables. --- .make/file | 2 +- .make/phony | 2 -- .make/{targets/phony/examples => rules/run} | 0 3 files changed, 1 insertion(+), 3 deletions(-) rename .make/{targets/phony/examples => rules/run} (100%) diff --git a/.make/file b/.make/file index 38ab880..9147fcf 100644 --- a/.make/file +++ b/.make/file @@ -21,7 +21,7 @@ include .make/compiler include .make/archiver # Rule templates -include $(addprefix .make/rules/,template objects libraries dependencies examples) +include $(addprefix .make/rules/,template objects libraries dependencies examples run) # Include the user's makefile, if it exists include $(wildcard make/file) diff --git a/.make/phony b/.make/phony index c87dd23..0306263 100644 --- a/.make/phony +++ b/.make/phony @@ -16,6 +16,4 @@ phony_targets += clean clean: rm -rf $(build_directory)/ -include .make/targets/phony/examples - .PHONY: $(phony_targets) diff --git a/.make/targets/phony/examples b/.make/rules/run similarity index 100% rename from .make/targets/phony/examples rename to .make/rules/run From 38d64b4335a9ed8a817c59a453659be28e12d779 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 29 Jun 2019 09:17:25 -0300 Subject: [PATCH 097/153] Define the as_library make function The to_library function now doesn't compute the shared object name of the library target. The new as_library function does that now. This allows placing all kinds of files in the libraries directory. --- .make/functions/path | 15 ++++++++++++++- .make/rules/libraries | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.make/functions/path b/.make/functions/path index 54f4401..c563e3a 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -18,6 +18,19 @@ to_object = $(addprefix $(build_objects_directory)/,$(addsuffix .o,$(basename $( # to_dependency = $(addprefix $(build_dependencies_directory)/,$(addsuffix .d,$(basename $(1)))) +# Converts the path to a library to the path to its corresponding target file. +# +# Arguments: +# $(1) = path to a library +# +# Variables: +# $(linkage) = linkage type: static | dynamic +# +# Returns: +# path to the library target +# +to_library = $(addprefix $(build_libraries_directory)/,$(1)) + # Converts a library name to the path to its corresponding library file. # # Arguments: @@ -29,7 +42,7 @@ to_dependency = $(addprefix $(build_dependencies_directory)/,$(addsuffix .d,$(ba # Returns: # path to the library target # -to_library = $(addprefix $(build_libraries_directory)/,$(call library.file_name,$(1),$(linkage))) +as_library = $(call to_library,$(call library.file_name,$(1),$(linkage))) # Converts an example source file path to its corresponding executable file path. # diff --git a/.make/rules/libraries b/.make/rules/libraries index 60d615a..25729f6 100644 --- a/.make/rules/libraries +++ b/.make/rules/libraries @@ -32,7 +32,7 @@ dynamic_library_rule_template = $(call rule_template,$(1),$$(call compiler.compi # Returns: # rules for generating library $(1) from the objects in $(2) # -library_rule_template = $(call $(linkage)_library_rule_template,$(call to_library,$(1)),$(2)) +library_rule_template = $(call $(linkage)_library_rule_template,$(call as_library,$(1)),$(2)) # Evaluates a library rule template for the current linkage. # From 29c615e086435cf92fc7f9a2e48e3816d0fa061c Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 29 Jun 2019 09:20:32 -0300 Subject: [PATCH 098/153] Use executable target names unchanged Executables can be made out of many object files so its name cannot be derived from them. It must be specified explicitly. --- .make/functions/path | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.make/functions/path b/.make/functions/path index c563e3a..f3f1bc4 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -44,12 +44,12 @@ to_library = $(addprefix $(build_libraries_directory)/,$(1)) # as_library = $(call to_library,$(call library.file_name,$(1),$(linkage))) -# Converts an example source file path to its corresponding executable file path. +# Converts an executable name to its corresponding executable file path. # # Arguments: -# $(1) = path to executable source file +# $(1) = name of the executable # # Returns: # path to the executable file # -to_executable = $(addprefix $(build_executables_directory)/,$(basename $(1))) +to_executable = $(addprefix $(build_executables_directory)/,$(1)) From c2f1fde84a8a2728d3c12f3c482afc4688e4ef1b Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 30 Jun 2019 23:51:59 -0300 Subject: [PATCH 099/153] Use the .PHONY target instead of phony_targets The prerequisites of a target don't have to be specified all at once. Targets X, Y and Z can be declared phony like this: .PHONY : X .PHONY : Y .PHONY : Z There is no point in collecting all phony targets in a variable just to specify them as the prerequisites of .PHONY later. --- .make/phony | 12 +++++------- .make/rules/run | 2 +- make/checkpatch | 2 +- make/system_call_lists | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.make/phony b/.make/phony index 0306263..08dded7 100644 --- a/.make/phony +++ b/.make/phony @@ -1,19 +1,17 @@ # Phony targets -phony_targets += library +.PHONY: library library: $(library) -phony_targets += startfiles +.PHONY: startfiles startfiles: $(objects_start) -phony_targets += examples +.PHONY: examples examples: $(examples_targets) -phony_targets += all +.PHONY: all all: library startfiles examples -phony_targets += clean +.PHONY: clean clean: rm -rf $(build_directory)/ - -.PHONY: $(phony_targets) diff --git a/.make/rules/run b/.make/rules/run index 7f79e82..ec0d3ea 100644 --- a/.make/rules/run +++ b/.make/rules/run @@ -1,7 +1,7 @@ configure_dynamic_loader = $(if $(call equal?,$(linkage),dynamic),LD_LIBRARY_PATH=$$(build_libraries_directory)) define generate_run_example_rule -phony_targets += run-$(2) +.PHONY : run-$(2) run-$(2) : $(1) $(call configure_dynamic_loader) $(1) diff --git a/make/checkpatch b/make/checkpatch index eef0199..a4823f4 100644 --- a/make/checkpatch +++ b/make/checkpatch @@ -11,7 +11,7 @@ $(checkpatch.pl): $(checkpatch_data_files) $(checkpatch_data_files): $(call download_linux_script,$@) -phony_targets += checkpatch +.PHONY : checkpatch checkpatch: $(checkpatch.pl) find $(include_directory) $(source_directory) $(start_directory) $(examples_directory) \ -type f \ diff --git a/make/system_call_lists b/make/system_call_lists index 24f6aa6..b53b39b 100644 --- a/make/system_call_lists +++ b/make/system_call_lists @@ -32,7 +32,7 @@ $(system-calls.missing) : $(system-calls.missing.sh) $(system-calls.available) $ # Phony targets define system_call_list_rule_template -phony_targets += system-calls.$(1) +.PHONY : system-calls.$(1) system-calls.$(1) : $$(system-calls.$(1)) cat $$< From 0e2353878acddb7c45b9750e41f67688197ede41 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 1 Jul 2019 00:39:25 -0300 Subject: [PATCH 100/153] Define make variable containing a newline Useful for placing newlines in places such as function call arguments. --- .make/definitions | 4 ++++ .make/file | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 .make/definitions diff --git a/.make/definitions b/.make/definitions new file mode 100644 index 0000000..1e4c38a --- /dev/null +++ b/.make/definitions @@ -0,0 +1,4 @@ +define \n := + + +endef diff --git a/.make/file b/.make/file index 9147fcf..1435b14 100644 --- a/.make/file +++ b/.make/file @@ -4,6 +4,9 @@ MAKEFLAGS += --no-builtin-rules --no-builtin-variables # Boolean logic in make include .make/logic +# Useful variables +include .make/definitions + # Commands used by the build system include .make/commands From 34d9ce398098d010a1ab0b828b0c669dc3f4cd0d Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 1 Jul 2019 00:20:27 -0300 Subject: [PATCH 101/153] Redesign the build system interface The new build system interface consists of variables containing all the information needed to build the project's targets. The names of these variables must follow a specific pattern. The new project function obtains the build data from these variables and uses it to generate the requested rules. Rule generation has been restructured around the most common compiler artifact: objects. The old rules for executables did not generate any objects at all. Now all source code is transformed into objects, and objects may become executables or libraries. --- .make/file | 8 +- .make/phony | 17 ---- .make/project | 218 +++++++++++++++++++++++++++++++++++++++++ .make/rules/examples | 31 ------ .make/rules/executable | 31 ++++++ .make/rules/run | 12 +-- make/examples | 2 - make/file | 60 +++++++++--- make/gcc_wrapper | 20 ---- make/libraries | 3 - make/objects | 4 - make/sources | 3 - make/start | 35 ------- 13 files changed, 304 insertions(+), 140 deletions(-) delete mode 100644 .make/phony create mode 100644 .make/project delete mode 100644 .make/rules/examples create mode 100644 .make/rules/executable delete mode 100644 make/examples delete mode 100644 make/gcc_wrapper delete mode 100644 make/libraries delete mode 100644 make/objects delete mode 100644 make/sources delete mode 100644 make/start diff --git a/.make/file b/.make/file index 1435b14..71a815c 100644 --- a/.make/file +++ b/.make/file @@ -24,13 +24,13 @@ include .make/compiler include .make/archiver # Rule templates -include $(addprefix .make/rules/,template objects libraries dependencies examples run) +include $(addprefix .make/rules/,template objects executable libraries dependencies run) + +# Project interface +include .make/project # Include the user's makefile, if it exists include $(wildcard make/file) # Include all generated dependency files include .make/dependencies - -# Additional phony targets and .PHONY variable -include .make/phony diff --git a/.make/phony b/.make/phony deleted file mode 100644 index 08dded7..0000000 --- a/.make/phony +++ /dev/null @@ -1,17 +0,0 @@ -# Phony targets - -.PHONY: library -library: $(library) - -.PHONY: startfiles -startfiles: $(objects_start) - -.PHONY: examples -examples: $(examples_targets) - -.PHONY: all -all: library startfiles examples - -.PHONY: clean -clean: - rm -rf $(build_directory)/ diff --git a/.make/project b/.make/project new file mode 100644 index 0000000..ff01f40 --- /dev/null +++ b/.make/project @@ -0,0 +1,218 @@ +project = $(call project.evaluate,$(1)) + +# Generates and evaluates rules for the given project. +# +# Arguments: +# $(1) = name of the project +# +project.evaluate = $(eval $(call project.generate,$(1))) + +# Generates rules for the given project. +# +# Arguments: +# $(1) = the project +# +# Variables: +# $($(1).targets) = targets to define rules for +# +define project.generate + +# $(0) +# $(1) + +$(call project.targets,$($(1).targets)) + +.PHONY : all +all : $($(1).targets) + +.PHONY : clean +clean: + rm -rf $(build_directory)/ + +# end $(0) + +endef + +# Generates rules for the given targets. +# +# Arguments: +# $(1) = the project's targets +# +project.targets = $(foreach target,$(1),$(call project.target,$(target))) + +# Generates rules appropriate for the given target's type. +# +# Arguments: +# $(1) = the project's target +# +# Variables: +# $($(1).type) = the type of the target: object | executable | library | recipe +# +project.target = $(call project.target.$($(1).type),$(1)) + +# Generates rules for compiling the given sources into objects. +# +# Generates a phony target to refer to the objects. +# +# Arguments: +# $(1) = the project's object target +# +# Variables: +# $($(1).sources) = source files to compile +# +define project.target.object + +# $(0) +# $(1) + +$(call project.target.object.rules,$(1)) + +.PHONY : $(1) +$(1) : $(call to_object,$($(1).sources)) + +# end $(0) + +endef + +# Generates rules for compiling the given sources into objects and dependency data files. +# +# Arguments: +# $(1) = the project's object target +# +# Variables: +# $($(1).sources) = source files to compile +# +define project.target.object.rules + +# $(0) +# $(1) + +$(foreach source,$($(1).sources),$(call generate_object_rule,$(source))$(\n)$(\n)$(call generate_dependency_file_rule,$(source),to_object)$(\n)$(\n)) + +# end $(0) + +endef + +# Generates rules for compiling the given sources into objects +# and for compiling the resulting objects into an executable. +# +# Generates a phony target to refer to the executable. +# Generates a phony target to run the executable. +# +# Arguments: +# $(1) = the project's executable target +# +# Variables: +# $($(1).sources) = source files to compile +# +define project.target.executable + +# $(0) +# $(1) + +$(call project.target.executable.rules,$(1)) + +.PHONY : $(1) +$(1) : $(call to_executable,$(1)) + +$(call generate_run_executable_rule,$(1)) + +# end $(0) + +endef + +# Generates rules for compiling the given sources into objects +# and for compiling the resulting objects into an executable. +# +# Arguments: +# $(1) = the project's executable target +# +# Variables: +# $($(1).sources) = source files to compile +# $($(1).dependencies) = additional dependencies for the executable target +# +define project.target.executable.rules + +# $(0) +# $(1) + +$(call project.target.object.rules,$(1)) + +$(call generate_executable_rule,$(1),$($(1).sources),$($(1).dependencies)) + +# end $(0) + +endef + + +# Generates rules for compiling the given sources into objects +# and for compiling the resulting objects into a library. +# +# Generates a phony target to refer to the library. +# +# Arguments: +# $(1) = the project's library target +# +# Variables: +# $($(1).sources) = source files to compile +# +define project.target.library + +# $(0) +# $(1) + +$(call project.target.library.rules,$(1)) + +.PHONY : $(1) +$(1) : $(call as_library,$($(1).name)) + +# end $(0) + +endef + +# Generates rules for the given library. +# +# Arguments: +# $(1) = the project's library target +# +# Variables: +# $($(1).name) = the name of the library +# $($(1).sources) = source files to compile +# +define project.target.library.rules + +# $(0) +# $(1) + +$(call project.target.object.rules,$(1)) + +$(call library_rule_template,$($(1).name),$(call to_object,$($(1).sources))) + +# end $(0) + +endef + +# Includes the given recipe in the generated rules. +# +# Generates a phony target to refer to the specified targets. +# +# Arguments: +# $(1) = the project's recipe target +# +# Variables: +# $($(1).recipe) = the recipe to include in the generated rules +# $($(1).targets) = the prerequisites of the phony target +# +define project.target.recipe + +# $(0) +# $(1) + +$($(1).recipe) + +.PHONY : $(1) +$(1) : $($(1).targets) + +# end $(0) + +endef diff --git a/.make/rules/examples b/.make/rules/examples deleted file mode 100644 index 578d693..0000000 --- a/.make/rules/examples +++ /dev/null @@ -1,31 +0,0 @@ -# Rule template for example executables. -# -# The reason why the executables depend on their dependency data file -# is to trigger the generation of their dependency data when they are updated. -# Once generated, future executions of make will include and benefit from the dependency data. -# Dependency data file generation rules are defined in .make/targets/dependencies. -# -# $(1) = path to source file -# $(2) = path to executable file -# $(3) = path to dependency data file -# -# References: -# -# https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete -# -define example_rule_template -examples_targets += $(2) - -$(2) : $(1) $(3) $$(library) $$(objects_start) $$(gcc_wrapper) - $$(call ensure_target_directory_exists) - $$(call gcc.compile_example,$$@,$$<,$$(linkage)) -endef - -# Computes the parameters for and evaluates the example rule template. -# -# $(1) = path to example source file -# -generate_example_rule = $(call example_rule_template,$(1),$(call to_executable,$(1)),$(call to_dependency,$(1))) - -# Compute list of all example targets -targets += $(examples_targets) diff --git a/.make/rules/executable b/.make/rules/executable new file mode 100644 index 0000000..49a997b --- /dev/null +++ b/.make/rules/executable @@ -0,0 +1,31 @@ +# Rule template for executables. +# +# The reason why the executables depend on their dependency data file +# is to trigger the generation of their dependency data when they are updated. +# Once generated, future executions of make will include and benefit from the dependency data. +# Dependency data file generation rules are defined in .make/targets/dependencies. +# +# $(1) = path to the executable file +# $(2) = paths to the object files +# $(3) = additional dependencies +# +# Returns: +# rules for compiling the objects in $(2) into the executable $(1) +# +# References: +# +# https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete +# +executable_rule_template = $(call rule_template,$(1),$$(call gcc.compile_example,$$@,$(2),$$(linkage)),$(2) $(3)) + +# Computes the parameters for and evaluates the executable rule template. +# +# $(1) = executable name +# $(2) = executable sources +# $(3) = additional dependencies +# +# Returns: +# rules for compiling the objects generated from the sources in $(2) +# into the executable named $(1) +# +generate_executable_rule = $(call executable_rule_template,$(call to_executable,$(1)),$(call to_object,$(2)),$(3)) diff --git a/.make/rules/run b/.make/rules/run index ec0d3ea..e162e6e 100644 --- a/.make/rules/run +++ b/.make/rules/run @@ -1,12 +1,10 @@ configure_dynamic_loader = $(if $(call equal?,$(linkage),dynamic),LD_LIBRARY_PATH=$$(build_libraries_directory)) -define generate_run_example_rule -.PHONY : run-$(2) +define run_executable_rule_template +.PHONY : run-$(1) -run-$(2) : $(1) - $(call configure_dynamic_loader) $(1) +run-$(1) : $(2) + $(call configure_dynamic_loader) $(2) endef -$(foreach example,$(sources_examples),$(eval $(call generate_run_example_rule,$(call to_executable,$(example)),$(basename $(example))))) - -undefine generate_run_example_rule +generate_run_executable_rule = $(call run_executable_rule_template,$(1),$(call to_executable,$(1))) diff --git a/make/examples b/make/examples deleted file mode 100644 index 71648f7..0000000 --- a/make/examples +++ /dev/null @@ -1,2 +0,0 @@ -# Generate example executable rules for every example source file -$(foreach example,$(sources_examples),$(eval $(call generate_example_rule,$(example))) $(eval $(call generate_dependency_file_rule,$(example),to_executable))) diff --git a/make/file b/make/file index 378f45d..2c31b6c 100644 --- a/make/file +++ b/make/file @@ -10,26 +10,58 @@ linkage ?= static # Project file system structure include make/structure -# Library sources -include make/sources +liblinux.targets := -# Object files resulting from the compilation of translation units -include make/objects +# System call library +liblinux.targets += library +library.type := library +library.name := linux +library.sources := $(call find,$(source_directory),file?) -# Static and dynamic libraries -include make/libraries +# Process startup code +liblinux.targets += startfiles +startfiles.type := object +startfiles.sources := $(call find,$(start_architecture_directory),file?) -# Targets for the liblinux process startup files -include make/start +# GCC linker specification file and wrapper script +# Makes it easy to build programs using liblinux +gcc_specs_script := $(scripts_directory)/liblinux.specs.sh +gcc_wrapper_script := $(scripts_directory)/liblinux-gcc.sh -# All objects -objects = $(objects_libraries) $(objects_start) +gcc_wrapper := $(call to_executable,liblinux-gcc) +gcc_specs := $(call to_library,liblinux.specs) -# The liblinux-gcc wrapper script and liblinux.specs file -include make/gcc_wrapper +liblinux.targets += liblinux-gcc +liblinux-gcc.type := recipe +liblinux-gcc.targets := $(gcc_wrapper) -# Generate targets for the library usage examples -include make/examples +define liblinux-gcc.recipe := + +$(gcc_wrapper) : $(gcc_specs) $(gcc_wrapper_script) + $(call mkdir_p,$(dir $(gcc_wrapper))) + $(gcc_wrapper_script) $(gcc_specs) > $(gcc_wrapper) + chmod +x $(gcc_wrapper) + +$(gcc_specs) : $(gcc_specs_script) $(call as_library,linux) $(call to_object,$(startfiles.sources)) + $(call mkdir_p,$(dir $(gcc_specs))) + $(gcc_specs_script) $(build_libraries_directory) $(call to_object,$(startfiles.sources)) > $(gcc_specs) + +endef + +# Library usage examples +define examples_template + +liblinux.targets += $(1) + +$(1).type := executable +$(1).sources := $(2) +$(1).dependencies := $(call to_executable,liblinux-gcc) + +endef + +$(foreach example,$(call glob,$(examples_directory)/*.c),$(eval $(call examples_template,$(basename $(notdir $(example))),$(example)))) + +$(call project,liblinux) include make/system_call_lists diff --git a/make/gcc_wrapper b/make/gcc_wrapper deleted file mode 100644 index 09217e6..0000000 --- a/make/gcc_wrapper +++ /dev/null @@ -1,20 +0,0 @@ -# GCC wrapper script and the specs file used by it -# Makes building example and application code painless - -# GCC linker specification file and wrapper script -gcc_specs_script := $(scripts_directory)/$(project).specs.sh -gcc_wrapper_script := $(scripts_directory)/$(project)-gcc.sh - -gcc_wrapper := $(build_scripts_directory)/$(notdir $(basename $(gcc_wrapper_script))) -gcc_specs := $(build_libraries_directory)/$(notdir $(basename $(gcc_specs_script))) - -$(gcc_wrapper) : $(gcc_specs) $(gcc_wrapper_script) - $(call ensure_target_directory_exists) - $(gcc_wrapper_script) $< > $@ - chmod +x $@ - -$(gcc_specs) : $(gcc_specs_script) - $(call ensure_target_directory_exists) - $(gcc_specs_script) $(build_libraries_directory) $(objects_start) > $@ - -targets += $(gcc_wrapper) $(gcc_specs) diff --git a/make/libraries b/make/libraries deleted file mode 100644 index 3f34043..0000000 --- a/make/libraries +++ /dev/null @@ -1,3 +0,0 @@ -library := $(call to_library,$(library_name)) - -$(call evaluate_library_rule,$(library_name),$(objects_library)) diff --git a/make/objects b/make/objects deleted file mode 100644 index 5e94e6e..0000000 --- a/make/objects +++ /dev/null @@ -1,4 +0,0 @@ -objects_library = $(call to_object,$(sources_library)) - -# Generate rules for object files and their dependency files -$(foreach source,$(sources_library),$(eval $(call generate_object_rule,$(source)) $(eval $(call generate_dependency_file_rule,$(source),to_object)))) diff --git a/make/sources b/make/sources deleted file mode 100644 index 86d7b6e..0000000 --- a/make/sources +++ /dev/null @@ -1,3 +0,0 @@ -sources_library = $(call find,$(source_directory),file?) -sources_start = $(call find,$(start_architecture_directory),file?) -sources_examples = $(call glob,$(examples_directory)/*.c) diff --git a/make/start b/make/start deleted file mode 100644 index e95d12d..0000000 --- a/make/start +++ /dev/null @@ -1,35 +0,0 @@ -# Converts the path to a startfile source to the path of its target. -# May be written in assembly or C. -# -# Arguments: -# $(1) = path to process startup source file -# -# Returns: -# path to the startfile target -# -source_to_start_object = $(patsubst $(start_architecture_directory)/%,$(build_start_directory)/%.o,$(basename $(1))) - -objects_start = $(call source_to_start_object,$(sources_start)) - -# Build targets for the liblinux process startup objects: -# -# _start.o -# liblinux_start.o - -# Rule template for process start objects. -# -# $(1) = path to start code file -# $(2) = path to start object file -# -define start_object_rule_template -$(call rule_template,$(2),$$(call compiler.compile_startup_object,$$@,$$<),$(1) $(3)) -endef - -# Computes the parameters for and evaluates the start object rule template. -# -# $(1) = path to start code file -# -generate_start_object_rule = $(call start_object_rule_template,$(1),$(call source_to_start_object,$(1)),$(call to_dependency,$(1))) - -# Generate start object rules for all start code files -$(foreach file,$(sources_start),$(eval $(call generate_start_object_rule,$(file))) $(eval $(call generate_dependency_file_rule,$(file),source_to_start_object))) From 153bb18c200301bc6b2dceec1c1a767620944eec Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 1 Jul 2019 00:48:31 -0300 Subject: [PATCH 102/153] Remove unused variables from make/file These variables were used to avoid repetition but are now conflicting with the new project function that is part of the redesigned API. --- make/file | 2 -- 1 file changed, 2 deletions(-) diff --git a/make/file b/make/file index 2c31b6c..e6fcd3c 100644 --- a/make/file +++ b/make/file @@ -1,5 +1,3 @@ -library_name := linux -project := lib$(library_name) C.freestanding := yes architecture ?= x86_64 From a73aef21f33c71f74e7135de13133d13defdd07d Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 1 Jul 2019 01:01:22 -0300 Subject: [PATCH 103/153] Set .DEFAULT_GOAL in the generated project rules Since lots of rules are generated and their order is undefined, it is wise to set make's default target explicitly. Normally, the default goal will be the first target of the project. In the following example project: example.targets := X Y Z The default target is X. This mirrors make's default behavior. The default target can also be specified explicitly: example.targets.default := Z --- .make/project | 3 +++ make/file | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.make/project b/.make/project index ff01f40..430af91 100644 --- a/.make/project +++ b/.make/project @@ -14,6 +14,7 @@ project.evaluate = $(eval $(call project.generate,$(1))) # # Variables: # $($(1).targets) = targets to define rules for +# $($(1).targets.default) = used as the default target if specified # define project.generate @@ -22,6 +23,8 @@ define project.generate $(call project.targets,$($(1).targets)) +.DEFAULT_GOAL := $(or $($(1).targets.default),$(firstword $($(1).targets))) + .PHONY : all all : $($(1).targets) diff --git a/make/file b/make/file index e6fcd3c..61874b6 100644 --- a/make/file +++ b/make/file @@ -3,8 +3,6 @@ C.freestanding := yes architecture ?= x86_64 linkage ?= static -.DEFAULT_GOAL := library - # Project file system structure include make/structure From e0716a88f179c48b2c891b9885b7baf8e461ad41 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 1 Jul 2019 06:06:26 -0300 Subject: [PATCH 104/153] Find the dependency files instead of using a list This removes the need to maintain a list of dependency files in the generated rules. --- .make/dependencies | 5 ++++- .make/rules/dependencies | 4 +--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.make/dependencies b/.make/dependencies index 4ecaff0..2ab7322 100644 --- a/.make/dependencies +++ b/.make/dependencies @@ -11,4 +11,7 @@ # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#include # https://make.mad-scientist.net/constructed-include-files/ # -include $(wildcard $(dependency_files)) + +dependency_file? = $(call boolean,$(and $(call equal?,$(suffix $(1)),.d),$(call file?,$(1)))) + +include $(call find,$(build_dependency_directory),dependency_file?) diff --git a/.make/rules/dependencies b/.make/rules/dependencies index b979539..26a5964 100644 --- a/.make/rules/dependencies +++ b/.make/rules/dependencies @@ -6,9 +6,9 @@ # to a list of paths to all its targets # define dependency_file_rule_template -dependency_files += $(2) $(call rule_template,$(2),$$(call compiler.generate_dependency_data,$$@,$$<,$$(call $(3),$$<)),$(1)) + endef # Computes the parameters for and evaluates the dependency file rule template. @@ -18,5 +18,3 @@ endef # to a list of paths to all its targets # generate_dependency_file_rule = $(call dependency_file_rule_template,$(1),$(call to_dependency,$(1)),$(2)) - -targets += $(dependency_files) From 4c7507e0fb67a934389073d9271af8091bcd1f10 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 1 Jul 2019 07:32:19 -0300 Subject: [PATCH 105/153] Parameterize directory creation in rule template This allows more than one directory to be created. --- .make/rules/dependencies | 2 +- .make/rules/executable | 2 +- .make/rules/libraries | 4 ++-- .make/rules/objects | 2 +- .make/rules/template | 3 ++- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.make/rules/dependencies b/.make/rules/dependencies index 26a5964..0e42f86 100644 --- a/.make/rules/dependencies +++ b/.make/rules/dependencies @@ -7,7 +7,7 @@ # define dependency_file_rule_template -$(call rule_template,$(2),$$(call compiler.generate_dependency_data,$$@,$$<,$$(call $(3),$$<)),$(1)) +$(call rule_template,$(2),$$(call compiler.generate_dependency_data,$$@,$$<,$$(call $(3),$$<)),$(1),$(dir $(2))) endef diff --git a/.make/rules/executable b/.make/rules/executable index 49a997b..cbffc73 100644 --- a/.make/rules/executable +++ b/.make/rules/executable @@ -16,7 +16,7 @@ # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -executable_rule_template = $(call rule_template,$(1),$$(call gcc.compile_example,$$@,$(2),$$(linkage)),$(2) $(3)) +executable_rule_template = $(call rule_template,$(1),$$(call gcc.compile_example,$$@,$(2),$$(linkage)),$(2) $(3),$(dir $(1))) # Computes the parameters for and evaluates the executable rule template. # diff --git a/.make/rules/libraries b/.make/rules/libraries index 25729f6..d78b636 100644 --- a/.make/rules/libraries +++ b/.make/rules/libraries @@ -7,7 +7,7 @@ # Returns: # rules for generating static library $(1) from the objects in $(2) # -static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create,$$@,$$^),$(2)) +static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create,$$@,$$^),$(2),$(dir $(1))) # Rule template for dynamic libraries. # @@ -18,7 +18,7 @@ static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create # Returns: # rules for generating dynamic library $(1) from the objects in $(2) # -dynamic_library_rule_template = $(call rule_template,$(1),$$(call compiler.compile_dynamic_library,$$@,$$^),$(2)) +dynamic_library_rule_template = $(call rule_template,$(1),$$(call compiler.compile_dynamic_library,$$@,$$^),$(2),$(dir $(1))) # Rule template for libraries corresponding to the current linkage. # diff --git a/.make/rules/objects b/.make/rules/objects index 8cc7939..f8c922c 100644 --- a/.make/rules/objects +++ b/.make/rules/objects @@ -13,7 +13,7 @@ # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -object_rule_template = $(call rule_template,$(2),$$(call compiler.compile_object,$$@,$$<,$$(linkage)),$(1) $(3)) +object_rule_template = $(call rule_template,$(2),$$(call compiler.compile_object,$$@,$$<,$$(linkage)),$(1) $(3),$(dir $(2) $(3))) # Computes the parameters for and evaluates the object rule template. # diff --git a/.make/rules/template b/.make/rules/template index ce7c2bb..2c73b86 100644 --- a/.make/rules/template +++ b/.make/rules/template @@ -5,12 +5,13 @@ # $(1) = path to target file # $(2) = command that generates $(1) # $(3) = optional dependencies list +# $(4) = directories to create # # Returns: # generated rule text for the given parameters # define rule_template $(1) : $(3) - $$(call ensure_target_directory_exists) + $(call mkdir_p,$(4)) $(2) endef From 65a07411c4679b8da2615c79d5c6e25c384228b0 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 1 Jul 2019 07:39:58 -0300 Subject: [PATCH 106/153] Pass source and target directly to the template The generated rules should be as simple and explicit as possible. They should not reference variables or functions from the framework. Automatic variables should also be avoided. --- .make/rules/dependencies | 2 +- .make/rules/executable | 2 +- .make/rules/libraries | 4 ++-- .make/rules/objects | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.make/rules/dependencies b/.make/rules/dependencies index 0e42f86..207b678 100644 --- a/.make/rules/dependencies +++ b/.make/rules/dependencies @@ -7,7 +7,7 @@ # define dependency_file_rule_template -$(call rule_template,$(2),$$(call compiler.generate_dependency_data,$$@,$$<,$$(call $(3),$$<)),$(1),$(dir $(2))) +$(call rule_template,$(2),$$(call compiler.generate_dependency_data,$(2),$(1),$$(call $(3),$(1))),$(1),$(dir $(2))) endef diff --git a/.make/rules/executable b/.make/rules/executable index cbffc73..384c531 100644 --- a/.make/rules/executable +++ b/.make/rules/executable @@ -16,7 +16,7 @@ # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -executable_rule_template = $(call rule_template,$(1),$$(call gcc.compile_example,$$@,$(2),$$(linkage)),$(2) $(3),$(dir $(1))) +executable_rule_template = $(call rule_template,$(1),$$(call gcc.compile_example,$(1),$(2),$$(linkage)),$(2) $(3),$(dir $(1))) # Computes the parameters for and evaluates the executable rule template. # diff --git a/.make/rules/libraries b/.make/rules/libraries index d78b636..efd4bcf 100644 --- a/.make/rules/libraries +++ b/.make/rules/libraries @@ -7,7 +7,7 @@ # Returns: # rules for generating static library $(1) from the objects in $(2) # -static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create,$$@,$$^),$(2),$(dir $(1))) +static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create,$(1),$(2)),$(2),$(dir $(1))) # Rule template for dynamic libraries. # @@ -18,7 +18,7 @@ static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create # Returns: # rules for generating dynamic library $(1) from the objects in $(2) # -dynamic_library_rule_template = $(call rule_template,$(1),$$(call compiler.compile_dynamic_library,$$@,$$^),$(2),$(dir $(1))) +dynamic_library_rule_template = $(call rule_template,$(1),$$(call compiler.compile_dynamic_library,$(1),$(2)),$(2),$(dir $(1))) # Rule template for libraries corresponding to the current linkage. # diff --git a/.make/rules/objects b/.make/rules/objects index f8c922c..92c1fc6 100644 --- a/.make/rules/objects +++ b/.make/rules/objects @@ -13,7 +13,7 @@ # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -object_rule_template = $(call rule_template,$(2),$$(call compiler.compile_object,$$@,$$<,$$(linkage)),$(1) $(3),$(dir $(2) $(3))) +object_rule_template = $(call rule_template,$(2),$$(call compiler.compile_object,$(2),$(1),$(linkage)),$(1) $(3),$(dir $(2) $(3))) # Computes the parameters for and evaluates the object rule template. # From b25176eba13ae463319ae1c5e659beabed37d559 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 1 Jul 2019 07:52:25 -0300 Subject: [PATCH 107/153] Pass the result of function calls to the templates The generated rules should be as simple and explicit as possible. They should not reference variables or functions from the framework. If the function call is escaped, it is passed as code to the template. This results in references to framework functions in the generated code. Simply passing the results of the functions as arguments avoids this. --- .make/rules/dependencies | 2 +- .make/rules/executable | 2 +- .make/rules/libraries | 4 ++-- .make/rules/objects | 2 +- .make/rules/run | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.make/rules/dependencies b/.make/rules/dependencies index 207b678..433e513 100644 --- a/.make/rules/dependencies +++ b/.make/rules/dependencies @@ -7,7 +7,7 @@ # define dependency_file_rule_template -$(call rule_template,$(2),$$(call compiler.generate_dependency_data,$(2),$(1),$$(call $(3),$(1))),$(1),$(dir $(2))) +$(call rule_template,$(2),$(call compiler.generate_dependency_data,$(2),$(1),$(call $(3),$(1))),$(1),$(dir $(2))) endef diff --git a/.make/rules/executable b/.make/rules/executable index 384c531..9cb41c4 100644 --- a/.make/rules/executable +++ b/.make/rules/executable @@ -16,7 +16,7 @@ # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -executable_rule_template = $(call rule_template,$(1),$$(call gcc.compile_example,$(1),$(2),$$(linkage)),$(2) $(3),$(dir $(1))) +executable_rule_template = $(call rule_template,$(1),$(call gcc.compile_example,$(1),$(2),$(linkage)),$(2) $(3),$(dir $(1))) # Computes the parameters for and evaluates the executable rule template. # diff --git a/.make/rules/libraries b/.make/rules/libraries index efd4bcf..55808db 100644 --- a/.make/rules/libraries +++ b/.make/rules/libraries @@ -7,7 +7,7 @@ # Returns: # rules for generating static library $(1) from the objects in $(2) # -static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create,$(1),$(2)),$(2),$(dir $(1))) +static_library_rule_template = $(call rule_template,$(1),$(call archiver.create,$(1),$(2)),$(2),$(dir $(1))) # Rule template for dynamic libraries. # @@ -18,7 +18,7 @@ static_library_rule_template = $(call rule_template,$(1),$$(call archiver.create # Returns: # rules for generating dynamic library $(1) from the objects in $(2) # -dynamic_library_rule_template = $(call rule_template,$(1),$$(call compiler.compile_dynamic_library,$(1),$(2)),$(2),$(dir $(1))) +dynamic_library_rule_template = $(call rule_template,$(1),$(call compiler.compile_dynamic_library,$(1),$(2)),$(2),$(dir $(1))) # Rule template for libraries corresponding to the current linkage. # diff --git a/.make/rules/objects b/.make/rules/objects index 92c1fc6..424ff18 100644 --- a/.make/rules/objects +++ b/.make/rules/objects @@ -13,7 +13,7 @@ # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -object_rule_template = $(call rule_template,$(2),$$(call compiler.compile_object,$(2),$(1),$(linkage)),$(1) $(3),$(dir $(2) $(3))) +object_rule_template = $(call rule_template,$(2),$(call compiler.compile_object,$(2),$(1),$(linkage)),$(1) $(3),$(dir $(2) $(3))) # Computes the parameters for and evaluates the object rule template. # diff --git a/.make/rules/run b/.make/rules/run index e162e6e..09036c8 100644 --- a/.make/rules/run +++ b/.make/rules/run @@ -1,4 +1,4 @@ -configure_dynamic_loader = $(if $(call equal?,$(linkage),dynamic),LD_LIBRARY_PATH=$$(build_libraries_directory)) +configure_dynamic_loader = $(if $(call equal?,$(linkage),dynamic),LD_LIBRARY_PATH=$(build_libraries_directory)) define run_executable_rule_template .PHONY : run-$(1) From 89d329fd77681a984d288f519873938924c4a158 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 1 Jul 2019 08:05:52 -0300 Subject: [PATCH 108/153] Generate .d files as a side effect of compilation Since keeping track of the dependency data files is no longer needed, they can be generated as a side effect of the compilation process. The build system will include all the dependency data files it finds. This is the state of the art of dependency tracking. References: http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ --- .make/compiler | 5 ++++- .make/compilers/gcc | 2 +- .make/file | 2 +- .make/project | 2 +- .make/rules/dependencies | 20 -------------------- .make/rules/objects | 2 +- 6 files changed, 8 insertions(+), 25 deletions(-) delete mode 100644 .make/rules/dependencies diff --git a/.make/compiler b/.make/compiler index efce533..ed0bdab 100644 --- a/.make/compiler +++ b/.make/compiler @@ -13,11 +13,14 @@ compiler_nostdlib_option := $($(compiler)_nostdlib_option) compiler_output_option = $($(compiler)_output_option) compiler_link_option = $($(compiler)_link_option) +compiler.options.dependency_data_generation = $(call $(compiler)_dependency_generation_options,$(1),$(2)) + define compiler.compile_object $(compiler) \ $(compiler_common_options) \ +$(call compiler.options.dependency_data_generation,$(3),$(1)) \ $(compiler_nostdlib_option) \ -$(call compiler_code_generation_options,$(3)) \ +$(call compiler_code_generation_options,$(4)) \ $(call compiler_output_option,$(1)) \ $(compiler_compile_option) $(2) endef diff --git a/.make/compilers/gcc b/.make/compilers/gcc index 00c2a8d..12d61d1 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -18,7 +18,7 @@ gcc_link_option = -l $(1) gcc_specs_option = -specs=$(1) gcc_code_generation_options = $(if $(call equal?,$(1),static),-fno-PIC,-fPIC) -gcc_dependency_generation_options = -M -MF $(1) $(foreach target,$(2),-MT $(target)) +gcc_dependency_generation_options = -MD -MF $(1) $(foreach target,$(2),-MT $(target)) # Common GCC options gcc_dialect_options = $(strip $(call gcc_standard_option,$(or $(1),c99)) $(if $(2),-ffreestanding)) diff --git a/.make/file b/.make/file index 71a815c..3fc8185 100644 --- a/.make/file +++ b/.make/file @@ -24,7 +24,7 @@ include .make/compiler include .make/archiver # Rule templates -include $(addprefix .make/rules/,template objects executable libraries dependencies run) +include $(addprefix .make/rules/,template objects executable libraries run) # Project interface include .make/project diff --git a/.make/project b/.make/project index 430af91..05ef6fe 100644 --- a/.make/project +++ b/.make/project @@ -90,7 +90,7 @@ define project.target.object.rules # $(0) # $(1) -$(foreach source,$($(1).sources),$(call generate_object_rule,$(source))$(\n)$(\n)$(call generate_dependency_file_rule,$(source),to_object)$(\n)$(\n)) +$(foreach source,$($(1).sources),$(call generate_object_rule,$(source))$(\n)$(\n)) # end $(0) diff --git a/.make/rules/dependencies b/.make/rules/dependencies deleted file mode 100644 index 433e513..0000000 --- a/.make/rules/dependencies +++ /dev/null @@ -1,20 +0,0 @@ -# Rule template for dependency data files. -# -# $(1) = path to source file -# $(2) = path to dependency file -# $(3) = make function that converts a path to a source file -# to a list of paths to all its targets -# -define dependency_file_rule_template - -$(call rule_template,$(2),$(call compiler.generate_dependency_data,$(2),$(1),$(call $(3),$(1))),$(1),$(dir $(2))) - -endef - -# Computes the parameters for and evaluates the dependency file rule template. -# -# $(1) = path to source source file -# $(2) = make function that converts a path to a source file -# to a list of paths to all its targets -# -generate_dependency_file_rule = $(call dependency_file_rule_template,$(1),$(call to_dependency,$(1)),$(2)) diff --git a/.make/rules/objects b/.make/rules/objects index 424ff18..a1228d5 100644 --- a/.make/rules/objects +++ b/.make/rules/objects @@ -13,7 +13,7 @@ # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -object_rule_template = $(call rule_template,$(2),$(call compiler.compile_object,$(2),$(1),$(linkage)),$(1) $(3),$(dir $(2) $(3))) +object_rule_template = $(call rule_template,$(2),$(call compiler.compile_object,$(2),$(1),$(3),$(linkage)),$(1),$(dir $(2) $(3))) # Computes the parameters for and evaluates the object rule template. # From bceed9a130ad7462c7cbc32a58a69209fc2b3e24 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 6 Jul 2019 08:53:29 -0300 Subject: [PATCH 109/153] Use correct variable name The build_dependency_directory variable does not exist. Referencing this variable results in an empty value which the find function maps to the current directory. The dependency_file? function correctly selects .d files for inclusion. Unlike the build_dependencies_directory variable, however, it does not take the current configuration into account. --- .make/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.make/dependencies b/.make/dependencies index 2ab7322..b197f0f 100644 --- a/.make/dependencies +++ b/.make/dependencies @@ -14,4 +14,4 @@ dependency_file? = $(call boolean,$(and $(call equal?,$(suffix $(1)),.d),$(call file?,$(1)))) -include $(call find,$(build_dependency_directory),dependency_file?) +include $(call find,$(build_dependencies_directory),dependency_file?) From 1314ff59538483bcc314e2dd724413782a266a04 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 6 Jul 2019 10:27:45 -0300 Subject: [PATCH 110/153] Define the dereference make function Accesses the value associated with a variable name. Although simple, it can be passed to other functions as an argument. It is also aliased as *, in order to be consistent with C's * operator. --- .make/all_functions | 1 + .make/functions/variables | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 .make/functions/variables diff --git a/.make/all_functions b/.make/all_functions index 141361b..f0d7e42 100644 --- a/.make/all_functions +++ b/.make/all_functions @@ -5,3 +5,4 @@ include .make/functions/library include .make/functions/path include .make/functions/recursion include .make/functions/shell +include .make/functions/variables diff --git a/.make/functions/variables b/.make/functions/variables new file mode 100644 index 0000000..2916708 --- /dev/null +++ b/.make/functions/variables @@ -0,0 +1,14 @@ +# Accesses the value associated with the given name. +# Useful for functional composition. +# +# Arguments: +# $(1) = name of the variable to dereference +# +# Variables: +# $($(1)) = the value that will be accessed +# +# Returns: +# the valuable of the variable +# +dereference = $($(1)) +* = $(call dereference,$(1)) From fadb6dfe54802d77f89ddd70972464ece03bb0e3 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 6 Jul 2019 10:38:07 -0300 Subject: [PATCH 111/153] Define the space make variable This variable contains a single space and is useful for writing spaces in places that can't normally contain spaces. --- .make/definitions | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.make/definitions b/.make/definitions index 1e4c38a..4cf622f 100644 --- a/.make/definitions +++ b/.make/definitions @@ -1,3 +1,6 @@ +space := +space += + define \n := From ebc769a7abb80ca741d75ec5b3f40fb275880209 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 6 Jul 2019 10:45:13 -0300 Subject: [PATCH 112/153] Define the map make function This fundamental algorithm transforms a list of values with a function. --- .make/all_functions | 1 + .make/functions/list | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 .make/functions/list diff --git a/.make/all_functions b/.make/all_functions index f0d7e42..7982005 100644 --- a/.make/all_functions +++ b/.make/all_functions @@ -2,6 +2,7 @@ include .make/functions/comparison include .make/functions/directory include .make/functions/file_system include .make/functions/library +include .make/functions/list include .make/functions/path include .make/functions/recursion include .make/functions/shell diff --git a/.make/functions/list b/.make/functions/list new file mode 100644 index 0000000..30e3f65 --- /dev/null +++ b/.make/functions/list @@ -0,0 +1,10 @@ +# Maps the given function to all values in the given list. +# +# Arguments: +# $(1) = function to map to values +# $(2) = list of values +# +# Returns: +# results of calling the $(1) function on each value of the $(2) list +# +map = $(foreach value,$(strip $(2)),$(call $(1),$(value))) From bcea4a053ce1cc28a1dce5d9335b7601ba5b7312 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 6 Jul 2019 10:48:48 -0300 Subject: [PATCH 113/153] Define the rest make function GNU make defines several functions for working with lists of values. There is a firstword function which is useful in recursive algorithms but unfortunately there is no rest function. --- .make/functions/list | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.make/functions/list b/.make/functions/list index 30e3f65..07f7aae 100644 --- a/.make/functions/list +++ b/.make/functions/list @@ -8,3 +8,13 @@ # results of calling the $(1) function on each value of the $(2) list # map = $(foreach value,$(strip $(2)),$(call $(1),$(value))) + +# Removes the first element of the list and returns the rest. +# +# Arguments: +# $(1) = list of values +# +# Returns: +# the list without the first element +# +rest = $(wordlist 2,$(words $(1)),$(1)) From b094f3737f149017834fe8d18080f4487627f5ac Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 6 Jul 2019 10:58:30 -0300 Subject: [PATCH 114/153] Define the resolve.name make function This function transforms a list of symbols into a variable name. --- .make/functions/variables | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.make/functions/variables b/.make/functions/variables index 2916708..f51e771 100644 --- a/.make/functions/variables +++ b/.make/functions/variables @@ -12,3 +12,17 @@ # dereference = $($(1)) * = $(call dereference,$(1)) + +# Resolves a composite variable name. +# +# Arguments: +# $(1) = list of variable name components in order +# $(2) = separator +# +# Defaults: +# $(2) = . +# +# Returns: +# the name of the variable +# +resolve.name = $(subst $(space),$(or $(2),.),$(strip $(1))) From 6798e8a1633b4a84cfc79bb7aa0a0844fd494bcd Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 6 Jul 2019 11:02:50 -0300 Subject: [PATCH 115/153] Define the defined? and undefined? make functions Makes it easy to check whether a variable is defined or undefined. --- .make/functions/variables | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.make/functions/variables b/.make/functions/variables index f51e771..5927107 100644 --- a/.make/functions/variables +++ b/.make/functions/variables @@ -26,3 +26,23 @@ dereference = $($(1)) # the name of the variable # resolve.name = $(subst $(space),$(or $(2),.),$(strip $(1))) + +# Tests whether the given variable is undefined. +# +# Arguments: +# $(1) = name of the variable +# +# Returns: +# whether the $(1) variable is undefined +# +undefined? = $(call boolean,$(call equal?,undefined,$(flavor $(1)))) + +# Tests whether the given variable is defined. +# +# Arguments: +# $(1) = name of the variable +# +# Returns: +# whether the $(1) variable is defined +# +defined? = $(call not,$(call undefined?,$(1))) From e950f165a7e014334068b8284f5f69df88e08255 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 7 Jul 2019 15:11:24 -0300 Subject: [PATCH 116/153] Define the resolve.value make function This function computes a variable name using resolve.name and then retrieves its value. --- .make/functions/variables | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.make/functions/variables b/.make/functions/variables index 5927107..c972588 100644 --- a/.make/functions/variables +++ b/.make/functions/variables @@ -27,6 +27,20 @@ dereference = $($(1)) # resolve.name = $(subst $(space),$(or $(2),.),$(strip $(1))) +# Resolves a composite variable name and retrieves its value. +# +# Arguments: +# $(1) = list of variable name components in order +# $(2) = separator +# +# Defaults: +# $(2) = . +# +# Returns: +# the value bound to the variable +# +resolve.value = $($(call resolve.name,$(1),$(2))) + # Tests whether the given variable is undefined. # # Arguments: From 3051ee5928045784dd4e405b24817b35e3a20e03 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 7 Jul 2019 15:47:49 -0300 Subject: [PATCH 117/153] Define the resolve make function This function computes the values of a variable nested in a list of namespaces. Should be useful for computing compiler flags for different contexts. Project, target and file contexts, for example. --- .make/functions/variables | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.make/functions/variables b/.make/functions/variables index c972588..dada890 100644 --- a/.make/functions/variables +++ b/.make/functions/variables @@ -41,6 +41,22 @@ resolve.name = $(subst $(space),$(or $(2),.),$(strip $(1))) # resolve.value = $($(call resolve.name,$(1),$(2))) +# Resolves a variable in a list of namespaces and retrieves their values. +# A namespace is the first component of a composite variable name. +# +# Arguments: +# $(1) = list of namespaces +# $(2) = variable to resolve +# $(3) = separator +# +# Defaults: +# $(3) = . +# +# Returns: +# the values bound to the variable $(1) inside all the namespaces in $(2) +# +resolve = $(strip $(foreach ns,$(1),$(call resolve.value,$(ns) $(2),$(3)))) + # Tests whether the given variable is undefined. # # Arguments: From c860fa67c56113ce0c17b02197f1b1fe064c7b04 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 7 Jul 2019 17:49:53 -0300 Subject: [PATCH 118/153] Define the resolve.first make function This function computes the value of the first defined variable in a list of namespaces. Should be useful when values set in specific contexts override values specified in more general contexts. For example, a project might want to use standard C99 for all targets except for a specific file which must be compiled with GNU extensions. --- .make/functions/variables | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.make/functions/variables b/.make/functions/variables index dada890..2265f65 100644 --- a/.make/functions/variables +++ b/.make/functions/variables @@ -76,3 +76,20 @@ undefined? = $(call boolean,$(call equal?,undefined,$(flavor $(1)))) # whether the $(1) variable is defined # defined? = $(call not,$(call undefined?,$(1))) + +# Resolves the value of the first defined variable in a list of namespaces. +# A namespace is the first component of a composite variable name. +# +# Arguments: +# $(1) = list of namespaces in order +# $(2) = variable to resolve +# $(3) = separator +# +# Defaults: +# $(3) = . +# +# Returns: +# the value of the first defined variable $(1) in the $(2) namespaces +# +resolve.first* = $(if $(call defined?,$(4)),$($(4)),$(call resolve.first,$(call rest,$(1)),$(2),$(3))) +resolve.first = $(if $(1),$(call $(0)*,$(1),$(2),$(3),$(call resolve.name,$(firstword $(1)) $(2),$(3)))) From eb2b77bf322ca3214242029253d12b38c7923e22 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 7 Jul 2019 17:54:32 -0300 Subject: [PATCH 119/153] Move up the defined? and undefined? functions They are fundamental building blocks for other functions. They should appear first in the file. --- .make/functions/variables | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.make/functions/variables b/.make/functions/variables index 2265f65..efcb243 100644 --- a/.make/functions/variables +++ b/.make/functions/variables @@ -13,6 +13,26 @@ dereference = $($(1)) * = $(call dereference,$(1)) +# Tests whether the given variable is undefined. +# +# Arguments: +# $(1) = name of the variable +# +# Returns: +# whether the $(1) variable is undefined +# +undefined? = $(call boolean,$(call equal?,undefined,$(flavor $(1)))) + +# Tests whether the given variable is defined. +# +# Arguments: +# $(1) = name of the variable +# +# Returns: +# whether the $(1) variable is defined +# +defined? = $(call not,$(call undefined?,$(1))) + # Resolves a composite variable name. # # Arguments: @@ -57,26 +77,6 @@ resolve.value = $($(call resolve.name,$(1),$(2))) # resolve = $(strip $(foreach ns,$(1),$(call resolve.value,$(ns) $(2),$(3)))) -# Tests whether the given variable is undefined. -# -# Arguments: -# $(1) = name of the variable -# -# Returns: -# whether the $(1) variable is undefined -# -undefined? = $(call boolean,$(call equal?,undefined,$(flavor $(1)))) - -# Tests whether the given variable is defined. -# -# Arguments: -# $(1) = name of the variable -# -# Returns: -# whether the $(1) variable is defined -# -defined? = $(call not,$(call undefined?,$(1))) - # Resolves the value of the first defined variable in a list of namespaces. # A namespace is the first component of a composite variable name. # From cbb54012e723550cd2c8b3e2376946e4f384883f Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 7 Jul 2019 17:59:06 -0300 Subject: [PATCH 120/153] Rename the resolve make function to resolve.all Since there is also a resolve.first function, the name should indicate what kind of resolution it applies. Namely, resolution of all values in the given namespaces. --- .make/functions/variables | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.make/functions/variables b/.make/functions/variables index efcb243..7530c8d 100644 --- a/.make/functions/variables +++ b/.make/functions/variables @@ -75,7 +75,7 @@ resolve.value = $($(call resolve.name,$(1),$(2))) # Returns: # the values bound to the variable $(1) inside all the namespaces in $(2) # -resolve = $(strip $(foreach ns,$(1),$(call resolve.value,$(ns) $(2),$(3)))) +resolve.all = $(strip $(foreach ns,$(1),$(call resolve.value,$(ns) $(2),$(3)))) # Resolves the value of the first defined variable in a list of namespaces. # A namespace is the first component of a composite variable name. From a90c559613bf53cf3cc7ac1c1ddb0c9b679b2a7e Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 07:52:00 -0300 Subject: [PATCH 121/153] Pass the current build stack to project functions The build stack captures the relationship between elements of the build. 1. The project is at the top of the stack. 2. Targets belong to the project. 3. Files belong to the targets. This abstraction will make it possible to apply different options to the whole project, to each target and even individual files. --- .make/project | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/.make/project b/.make/project index 05ef6fe..ca92d57 100644 --- a/.make/project +++ b/.make/project @@ -21,7 +21,7 @@ define project.generate # $(0) # $(1) -$(call project.targets,$($(1).targets)) +$(call project.targets,$($(1).targets),$(1)) .DEFAULT_GOAL := $(or $($(1).targets.default),$(firstword $($(1).targets))) @@ -40,18 +40,20 @@ endef # # Arguments: # $(1) = the project's targets +# $(2) = build stack # -project.targets = $(foreach target,$(1),$(call project.target,$(target))) +project.targets = $(foreach target,$(1),$(call project.target,$(target),$(2) $(target))) # Generates rules appropriate for the given target's type. # # Arguments: # $(1) = the project's target +# $(2) = build stack # # Variables: # $($(1).type) = the type of the target: object | executable | library | recipe # -project.target = $(call project.target.$($(1).type),$(1)) +project.target = $(call project.target.$($(1).type),$(1),$(2)) # Generates rules for compiling the given sources into objects. # @@ -59,6 +61,7 @@ project.target = $(call project.target.$($(1).type),$(1)) # # Arguments: # $(1) = the project's object target +# $(2) = build stack # # Variables: # $($(1).sources) = source files to compile @@ -67,8 +70,9 @@ define project.target.object # $(0) # $(1) +# $(2) -$(call project.target.object.rules,$(1)) +$(call project.target.object.rules,$(1),$(2)) .PHONY : $(1) $(1) : $(call to_object,$($(1).sources)) @@ -81,6 +85,7 @@ endef # # Arguments: # $(1) = the project's object target +# $(2) = build stack # # Variables: # $($(1).sources) = source files to compile @@ -89,6 +94,7 @@ define project.target.object.rules # $(0) # $(1) +# $(2) $(foreach source,$($(1).sources),$(call generate_object_rule,$(source))$(\n)$(\n)) @@ -104,6 +110,7 @@ endef # # Arguments: # $(1) = the project's executable target +# $(2) = build stack # # Variables: # $($(1).sources) = source files to compile @@ -112,8 +119,9 @@ define project.target.executable # $(0) # $(1) +# $(2) -$(call project.target.executable.rules,$(1)) +$(call project.target.executable.rules,$(1),$(2)) .PHONY : $(1) $(1) : $(call to_executable,$(1)) @@ -129,6 +137,7 @@ endef # # Arguments: # $(1) = the project's executable target +# $(2) = build stack # # Variables: # $($(1).sources) = source files to compile @@ -138,8 +147,9 @@ define project.target.executable.rules # $(0) # $(1) +# $(2) -$(call project.target.object.rules,$(1)) +$(call project.target.object.rules,$(1),$(2)) $(call generate_executable_rule,$(1),$($(1).sources),$($(1).dependencies)) @@ -155,6 +165,7 @@ endef # # Arguments: # $(1) = the project's library target +# $(2) = build stack # # Variables: # $($(1).sources) = source files to compile @@ -163,8 +174,9 @@ define project.target.library # $(0) # $(1) +# $(2) -$(call project.target.library.rules,$(1)) +$(call project.target.library.rules,$(1),$(2)) .PHONY : $(1) $(1) : $(call as_library,$($(1).name)) @@ -177,6 +189,7 @@ endef # # Arguments: # $(1) = the project's library target +# $(2) = build stack # # Variables: # $($(1).name) = the name of the library @@ -186,8 +199,9 @@ define project.target.library.rules # $(0) # $(1) +# $(2) -$(call project.target.object.rules,$(1)) +$(call project.target.object.rules,$(1),$(2)) $(call library_rule_template,$($(1).name),$(call to_object,$($(1).sources))) @@ -201,6 +215,7 @@ endef # # Arguments: # $(1) = the project's recipe target +# $(2) = build stack # # Variables: # $($(1).recipe) = the recipe to include in the generated rules @@ -210,6 +225,7 @@ define project.target.recipe # $(0) # $(1) +# $(2) $($(1).recipe) From 3d652f5a760d243b235b0fdfe36797234557f1c1 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 08:48:38 -0300 Subject: [PATCH 122/153] Define rule generation function for source files This function receives as part of the build stack the object file that will be generated from the given source file. Makes the code easier to understand by generating rules for one object and leaving the list of sources to the calling function. Makes the newline variables unnecessary. --- .make/project | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.make/project b/.make/project index ca92d57..f962a2c 100644 --- a/.make/project +++ b/.make/project @@ -96,7 +96,25 @@ define project.target.object.rules # $(1) # $(2) -$(foreach source,$($(1).sources),$(call generate_object_rule,$(source))$(\n)$(\n)) +$(foreach source,$($(1).sources),$(call $(0).file,$(source),$(2) $(call to_object,$(source)))) + +# end $(0) + +endef + +# Generates rules for compiling the given source into object and dependency data files. +# +# Arguments: +# $(1) = the source file +# $(2) = build stack +# +define project.target.object.rules.file + +# $(0) +# $(1) +# $(2) + +$(call generate_object_rule,$(1)) # end $(0) From 3c92ea57409cd1f55e217a1602d821ae3a94b979 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 12:50:40 -0300 Subject: [PATCH 123/153] Improve documentation of rule template arguments Make them follow the new format. --- .make/rules/executable | 14 ++++++++------ .make/rules/objects | 10 ++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.make/rules/executable b/.make/rules/executable index 9cb41c4..3238462 100644 --- a/.make/rules/executable +++ b/.make/rules/executable @@ -5,9 +5,10 @@ # Once generated, future executions of make will include and benefit from the dependency data. # Dependency data file generation rules are defined in .make/targets/dependencies. # -# $(1) = path to the executable file -# $(2) = paths to the object files -# $(3) = additional dependencies +# Arguments: +# $(1) = path to the executable file +# $(2) = paths to the object files +# $(3) = additional dependencies # # Returns: # rules for compiling the objects in $(2) into the executable $(1) @@ -20,9 +21,10 @@ executable_rule_template = $(call rule_template,$(1),$(call gcc.compile_example, # Computes the parameters for and evaluates the executable rule template. # -# $(1) = executable name -# $(2) = executable sources -# $(3) = additional dependencies +# Arguments: +# $(1) = executable name +# $(2) = executable sources +# $(3) = additional dependencies # # Returns: # rules for compiling the objects generated from the sources in $(2) diff --git a/.make/rules/objects b/.make/rules/objects index a1228d5..4797919 100644 --- a/.make/rules/objects +++ b/.make/rules/objects @@ -5,9 +5,10 @@ # Once generated, future executions of make will include and benefit from the dependency data. # Dependency data file generation rules are defined in .make/targets/dependencies. # -# $(1) = path to source file -# $(2) = path to object file -# $(3) = path to dependency data file +# Arguments: +# $(1) = path to source file +# $(2) = path to object file +# $(3) = path to dependency data file # # References: # @@ -17,7 +18,8 @@ object_rule_template = $(call rule_template,$(2),$(call compiler.compile_object, # Computes the parameters for and evaluates the object rule template. # -# $(1) = path to source file +# Arguments: +# $(1) = path to source file # generate_object_rule = $(call object_rule_template,$(1),$(call to_object,$(1)),$(call to_dependency,$(1))) From ac357ba0d94ad0abb83cba9a632720c47e5114ae Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 13:30:27 -0300 Subject: [PATCH 124/153] Define the reverse make function This function reverses the order of the elements in the given list. --- .make/functions/list | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.make/functions/list b/.make/functions/list index 07f7aae..fd244ec 100644 --- a/.make/functions/list +++ b/.make/functions/list @@ -18,3 +18,13 @@ map = $(foreach value,$(strip $(2)),$(call $(1),$(value))) # the list without the first element # rest = $(wordlist 2,$(words $(1)),$(1)) + +# Inverts the order of the elements of the list. +# +# Arguments: +# $(1) = list of values +# +# Returns: +# the reversed list reversed +# +reverse = $(if $(word 2,$(1)),$(call reverse,$(call rest,$(1))) $(firstword $(1)),$(1)) From 03103b55899c422837ffc6e564225868fceaeba1 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 14:08:13 -0300 Subject: [PATCH 125/153] Support extra dependencies in rule templates The library and object rule template functions now propagate additional dependencies to the general rule template function. This brings those functions to feature parity with the executable rule template function. --- .make/project | 10 +++++++--- .make/rules/libraries | 12 ++++++++---- .make/rules/objects | 7 ++++--- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.make/project b/.make/project index f962a2c..b1cf9ba 100644 --- a/.make/project +++ b/.make/project @@ -89,6 +89,7 @@ endef # # Variables: # $($(1).sources) = source files to compile +# $($(1).dependencies) = additional dependencies for the objects # define project.target.object.rules @@ -96,7 +97,7 @@ define project.target.object.rules # $(1) # $(2) -$(foreach source,$($(1).sources),$(call $(0).file,$(source),$(2) $(call to_object,$(source)))) +$(foreach source,$($(1).sources),$(call $(0).file,$(source),$(2) $(call to_object,$(source)),$($(1).dependencies))) # end $(0) @@ -107,14 +108,16 @@ endef # Arguments: # $(1) = the source file # $(2) = build stack +# $(3) = additional dependencies for the object # define project.target.object.rules.file # $(0) # $(1) # $(2) +# $(3) -$(call generate_object_rule,$(1)) +$(call generate_object_rule,$(1),$(3)) # end $(0) @@ -212,6 +215,7 @@ endef # Variables: # $($(1).name) = the name of the library # $($(1).sources) = source files to compile +# $($(1).dependencies) = additional dependencies for the library # define project.target.library.rules @@ -221,7 +225,7 @@ define project.target.library.rules $(call project.target.object.rules,$(1),$(2)) -$(call library_rule_template,$($(1).name),$(call to_object,$($(1).sources))) +$(call library_rule_template,$($(1).name),$(call to_object,$($(1).sources)),$($(1).dependencies)) # end $(0) diff --git a/.make/rules/libraries b/.make/rules/libraries index 55808db..9ab912a 100644 --- a/.make/rules/libraries +++ b/.make/rules/libraries @@ -3,28 +3,31 @@ # Arguments: # $(1) = path to static library # $(2) = list of object files +# $(3) = additional dependencies # # Returns: # rules for generating static library $(1) from the objects in $(2) # -static_library_rule_template = $(call rule_template,$(1),$(call archiver.create,$(1),$(2)),$(2),$(dir $(1))) +static_library_rule_template = $(call rule_template,$(1),$(call archiver.create,$(1),$(2)),$(2) $(3),$(dir $(1))) # Rule template for dynamic libraries. # # Arguments: # $(1) = path to dynamic library # $(2) = list of object files +# $(3) = additional dependencies # # Returns: # rules for generating dynamic library $(1) from the objects in $(2) # -dynamic_library_rule_template = $(call rule_template,$(1),$(call compiler.compile_dynamic_library,$(1),$(2)),$(2),$(dir $(1))) +dynamic_library_rule_template = $(call rule_template,$(1),$(call compiler.compile_dynamic_library,$(1),$(2)),$(2) $(3),$(dir $(1))) # Rule template for libraries corresponding to the current linkage. # # Arguments: # $(1) = library name # $(2) = list of object files +# $(3) = additional dependencies # # Variables: # $(linkage) = linkage type: static | dynamic @@ -32,13 +35,14 @@ dynamic_library_rule_template = $(call rule_template,$(1),$(call compiler.compil # Returns: # rules for generating library $(1) from the objects in $(2) # -library_rule_template = $(call $(linkage)_library_rule_template,$(call as_library,$(1)),$(2)) +library_rule_template = $(call $(linkage)_library_rule_template,$(call as_library,$(1)),$(2),$(3)) # Evaluates a library rule template for the current linkage. # # Arguments: # $(1) = library name # $(2) = list of object files +# $(3) = additional dependencies # # Variables: # $(linkage) = linkage type: static | dynamic @@ -46,4 +50,4 @@ library_rule_template = $(call $(linkage)_library_rule_template,$(call as_librar # Returns: # ε # -evaluate_library_rule = $(eval $(call library_rule_template,$(1),$(2))) +evaluate_library_rule = $(eval $(call library_rule_template,$(1),$(2),$(3))) diff --git a/.make/rules/objects b/.make/rules/objects index 4797919..93ec40e 100644 --- a/.make/rules/objects +++ b/.make/rules/objects @@ -9,17 +9,18 @@ # $(1) = path to source file # $(2) = path to object file # $(3) = path to dependency data file +# $(4) = additional dependencies # # References: # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -object_rule_template = $(call rule_template,$(2),$(call compiler.compile_object,$(2),$(1),$(3),$(linkage)),$(1),$(dir $(2) $(3))) +object_rule_template = $(call rule_template,$(2),$(call compiler.compile_object,$(2),$(1),$(3),$(linkage)),$(1) $(4),$(dir $(2) $(3))) # Computes the parameters for and evaluates the object rule template. # # Arguments: # $(1) = path to source file +# $(2) = additional dependencies # -generate_object_rule = $(call object_rule_template,$(1),$(call to_object,$(1)),$(call to_dependency,$(1))) - +generate_object_rule = $(call object_rule_template,$(1),$(call to_object,$(1)),$(call to_dependency,$(1)),$(2)) From 8176ccc812905f46cbd0bf82d717b5eced9f292a Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 14:55:18 -0300 Subject: [PATCH 126/153] Remove unused build directory variables The scripts and libraries/start nodes no longer exist in the build tree. These variables are not used anymore. --- .make/structure | 3 --- 1 file changed, 3 deletions(-) diff --git a/.make/structure b/.make/structure index 13ae2df..4e248cc 100644 --- a/.make/structure +++ b/.make/structure @@ -5,14 +5,11 @@ build_root_directory = $(build_directory)/$(configuration) build_objects_directory = $(build_root_directory)/objects build_libraries_directory = $(build_root_directory)/libraries -build_start_directory = $(build_libraries_directory)/$(start_directory) build_executables_directory = $(build_root_directory)/executables build_dependencies_directory = $(build_root_directory)/dependencies -build_scripts_directory = $(build_root_directory)/$(scripts_directory) - # If the build directory is a symbolic link to another directory, # ensure the existence of that directory. build_directory_link := $(shell readlink $(build_directory)) From 528f238bedc7954323ac3fd176df48bf5a4d163c Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 16:13:56 -0300 Subject: [PATCH 127/153] Define the coalesce make function This function joins all values of the given list. It's called coalesce because GNU make already defines a join function. --- .make/functions/list | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.make/functions/list b/.make/functions/list index fd244ec..ba84cad 100644 --- a/.make/functions/list +++ b/.make/functions/list @@ -28,3 +28,15 @@ rest = $(wordlist 2,$(words $(1)),$(1)) # the reversed list reversed # reverse = $(if $(word 2,$(1)),$(call reverse,$(call rest,$(1))) $(firstword $(1)),$(1)) + +# Joins all elements of the given list. +# +# Arguments: +# $(1) = list of values +# $(2) = optional separator +# +# Returns: +# elements of $(1) combined into one +# +coalesce* = $(if $(2),$(addprefix $(addsuffix $(3),$(1)),$(2)),$(1)) +coalesce = $(if $(word 2,$(1)),$(call $(0)*,$(firstword $(1)),$(call $(0),$(call rest,$(1)),$(2)),$(2)),$(1)) From be056e6f39a7d84a468ee8ccdeb5b6be849f7c4c Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 16:17:59 -0300 Subject: [PATCH 128/153] Define the path.separator make variable This variable represents the file system path separator. It can be customized on systems that don't use forward slash. --- .make/functions/path | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.make/functions/path b/.make/functions/path index f3f1bc4..d084444 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -1,3 +1,6 @@ +# File system path separator. Specific to each operating system. +path.separator ?= / + # Converts a source file path to its corresponding object file path. # # Arguments: From 11d2b2c195d929f16ae95e116899502ea7bf96dc Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 16:19:40 -0300 Subject: [PATCH 129/153] Define the path.join make function This function joins elements of a list to form a new file system path. --- .make/functions/path | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.make/functions/path b/.make/functions/path index d084444..afd473e 100644 --- a/.make/functions/path +++ b/.make/functions/path @@ -1,6 +1,20 @@ # File system path separator. Specific to each operating system. path.separator ?= / +# Forms a new path by joining all the given elements. +# +# Arguments: +# $(1) = list of paths to join +# $(2) = path separator +# +# Defaults: +# $(2) = $(path.separator) +# +# Returns: +# all elements in $(1) joined into one path +# +path.join = $(call coalesce,$(1),$(or $(2),$(path.separator))) + # Converts a source file path to its corresponding object file path. # # Arguments: From 7b3e783833aa64ef805768d52e481ffe03259fb6 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 16:28:36 -0300 Subject: [PATCH 130/153] Define the configuration.separator make variable This allows customizing the name of the configuration directory. --- .make/configuration | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.make/configuration b/.make/configuration index d184582..bbcaf62 100644 --- a/.make/configuration +++ b/.make/configuration @@ -1 +1,2 @@ -configuration = $(architecture)-$(linkage) +configuration.separator ?= - +configuration = $(architecture)$(configuration.separator)$(linkage) From fa74735ce9e6832b21665182504e893a4b100149 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 16:34:14 -0300 Subject: [PATCH 131/153] Define the configuration.current make variable It takes the value of the configuration variable into account, leaving its definition to the user of the build system. It is now possible to customize the configuration variable. If left undefined, the build system will simply not create configuration directories in the build tree. --- .make/configuration | 2 +- .make/structure | 2 +- make/file | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.make/configuration b/.make/configuration index bbcaf62..1e28e5d 100644 --- a/.make/configuration +++ b/.make/configuration @@ -1,2 +1,2 @@ configuration.separator ?= - -configuration = $(architecture)$(configuration.separator)$(linkage) +configuration.current = $(call coalesce,$(configuration),$(configuration.separator)) diff --git a/.make/structure b/.make/structure index 4e248cc..30cf7c9 100644 --- a/.make/structure +++ b/.make/structure @@ -1,6 +1,6 @@ # Directories for build artifacts build_directory ?= build -build_root_directory = $(build_directory)/$(configuration) +build_root_directory = $(call path.join,$(build_directory) $(configuration.current)) build_objects_directory = $(build_root_directory)/objects diff --git a/make/file b/make/file index 61874b6..3dd0e48 100644 --- a/make/file +++ b/make/file @@ -3,6 +3,8 @@ C.freestanding := yes architecture ?= x86_64 linkage ?= static +configuration := $(architecture) $(linkage) + # Project file system structure include make/structure From 1c4da5813a3919335758ac438fdb7d9fb0115065 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 16:40:41 -0300 Subject: [PATCH 132/153] Use path.join to define the build directories Should make it easier to work with the build tree. --- .make/structure | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.make/structure b/.make/structure index 30cf7c9..ccf349c 100644 --- a/.make/structure +++ b/.make/structure @@ -2,13 +2,13 @@ build_directory ?= build build_root_directory = $(call path.join,$(build_directory) $(configuration.current)) -build_objects_directory = $(build_root_directory)/objects +build_objects_directory = $(call path.join,$(build_root_directory) objects) -build_libraries_directory = $(build_root_directory)/libraries +build_libraries_directory = $(call path.join,$(build_root_directory) libraries) -build_executables_directory = $(build_root_directory)/executables +build_executables_directory = $(call path.join,$(build_root_directory) executables) -build_dependencies_directory = $(build_root_directory)/dependencies +build_dependencies_directory = $(call path.join,$(build_root_directory) dependencies) # If the build directory is a symbolic link to another directory, # ensure the existence of that directory. From ac54c4b621d3e6f0801ad92e253a5117884b05fb Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 16:55:24 -0300 Subject: [PATCH 133/153] Define the gcc.compile make function The first step towards revamping the compiler interface. --- .make/compilers/gcc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index 12d61d1..c0121fb 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -63,3 +63,23 @@ $(gcc_list_macro_names_option) \ $(call gcc_include_macros_option,$(1)) \ $(gcc_null_input) endef + +# Generates a GCC command line that compiles a source file into an object file. +# +# Arguments: +# $(1) = source file +# $(2) = object file +# $(3) = dependency data file +# $(4) = options +# $(5) = GCC executable to use +# +# Returns: +# command line that compiles $(1) into $(2) using the options in $(4) +# +define gcc.compile +$(or $(5),$(gcc)) \ +$(4) \ +$(call gcc_dependency_generation_options,$(3),$(2)) \ +$(call gcc_output_option,$(2)) \ +$(gcc_compile_option) $(1) +endef From 4610c6e7608e70f0db51c745fe195875bdaf9827 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 16:59:19 -0300 Subject: [PATCH 134/153] Add the compiler to the configuration The compiler makes a huge difference in the output. The build configuration should contain the chosen compiler when multiple compilers are supported by the project. --- make/file | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/make/file b/make/file index 3dd0e48..c64df86 100644 --- a/make/file +++ b/make/file @@ -2,8 +2,9 @@ C.freestanding := yes architecture ?= x86_64 linkage ?= static +compiler ?= gcc -configuration := $(architecture) $(linkage) +configuration := $(architecture) $(linkage) $(compiler) # Project file system structure include make/structure From 3ea38113613e40dfca310f39dfece6fba7b5bd97 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 18:39:32 -0300 Subject: [PATCH 135/153] Define the gcc.link function This function generates a GCC command line that links objects and produces an executable or dynamic library. --- .make/compilers/gcc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index c0121fb..061aa2e 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -83,3 +83,21 @@ $(call gcc_dependency_generation_options,$(3),$(2)) \ $(call gcc_output_option,$(2)) \ $(gcc_compile_option) $(1) endef + +# Generates a GCC command line that links object files. +# +# Arguments: +# $(1) = object files +# $(2) = output file +# $(3) = options +# $(4) = GCC executable to use +# +# Returns: +# command line that compiles $(1) into $(2) using the options in $(4) +# +define gcc.link +$(or $(4),$(gcc)) \ +$(3) \ +$(call gcc_output_option,$(2)) \ +$(1) +endef From ca9fa38e70c5b7b4be6c8385352889ac0bea9633 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Thu, 11 Jul 2019 20:25:49 -0300 Subject: [PATCH 136/153] Redesign the build system's compiler interface Now the project can specify the compiler and linker options. All lists of compiler and linker options are merged. The most specific compiler and linker choices are applied. This allows multiscope configuration of compilation and linking. --- .make/project | 143 ++++++++++++++++++++++++++++++++++++++++- .make/rules/executable | 10 ++- .make/rules/libraries | 10 ++- .make/rules/objects | 10 ++- make/file | 21 +++++- 5 files changed, 184 insertions(+), 10 deletions(-) diff --git a/.make/project b/.make/project index b1cf9ba..99f1d9d 100644 --- a/.make/project +++ b/.make/project @@ -117,7 +117,49 @@ define project.target.object.rules.file # $(2) # $(3) -$(call generate_object_rule,$(1),$(3)) +$(call $(0)*,$(1),$(2),$(3),$(call resolve.first,$(call reverse,$(2)),compiler)) + +# end $(0) + +endef + +# Arguments: +# $(1) = the source file +# $(2) = build stack +# $(3) = additional dependencies for the object +# $(4) = compiler to use +# +define project.target.object.rules.file* + +# $(0) +# $(1) +# $(2) +# $(3) +# $(4) + +$(call $(0)*,$(1),$(3),$(4),$(call resolve.all,$(2),compiler $(4) options),$(call resolve.first,$(call reverse,$(2)),compiler $(4))) + +# end $(0) + +endef + +# Arguments: +# $(1) = the source file +# $(2) = additional dependencies for the object +# $(3) = compiler to use +# $(4) = compiler options +# $(5) = compiler executable +# +define project.target.object.rules.file** + +# $(0) +# $(1) +# $(2) +# $(3) +# $(4) +# $(5) + +$(call generate_object_rule,$(1),$(2),$(3),$(4),$(5)) # end $(0) @@ -172,12 +214,57 @@ define project.target.executable.rules $(call project.target.object.rules,$(1),$(2)) -$(call generate_executable_rule,$(1),$($(1).sources),$($(1).dependencies)) +$(call $(0).file,$(1),$(2),$($(1).sources),$($(1).dependencies),$(call resolve.first,$(call reverse,$(2)),linker)) + +# end $(0) + +endef + +# Arguments: +# $(1) = the project's executable target +# $(2) = build stack +# $(3) = sources +# $(4) = additional dependencies +# $(5) = linker to use +# +define project.target.executable.rules.file + +# $(0) +# $(1) +# $(2) +# $(3) +# $(4) +# $(5) + +$(call $(0)*,$(1),$(3),$(4),$(5),$(call resolve.all,$(2),linker $(5) options),$(call resolve.first,$(call reverse,$(2)),linker $(5))) # end $(0) endef +# Arguments: +# $(1) = the project's executable target +# $(2) = sources +# $(3) = additional dependencies +# $(4) = compiler to use +# $(5) = compiler options +# $(6) = compiler executable +# +define project.target.executable.rules.file* + +# $(0) +# $(1) +# $(2) +# $(3) +# $(4) +# $(5) +# $(6) + +$(call generate_executable_rule,$(1),$(2),$(3),$(4),$(5),$(6)) + +# end $(0) + +endef # Generates rules for compiling the given sources into objects # and for compiling the resulting objects into a library. @@ -225,7 +312,57 @@ define project.target.library.rules $(call project.target.object.rules,$(1),$(2)) -$(call library_rule_template,$($(1).name),$(call to_object,$($(1).sources)),$($(1).dependencies)) +$(call $(0).file,$(1),$(2),$($(1).name),$(call to_object,$($(1).sources)),$($(1).dependencies),$(call resolve.first,$(call reverse,$(2)),linker)) + +# end $(0) + +endef + +# Generates rules for the given library. +# +# Arguments: +# $(1) = the project's library target +# $(2) = build stack +# $(3) = library name +# $(4) = library objects +# $(5) = additional dependencies +# $(6) = linker to use +# +define project.target.library.rules.file + +# $(0) +# $(1) +# $(2) +# $(3) +# $(4) +# $(5) +# $(6) + +$(call $(0)*,$(3),$(4),$(5),$(6),$(call resolve.all,$(2),linker $(6) options),$(call resolve.first,$(call reverse,$(2)),linker $(6))) + +# end $(0) + +endef + +# Arguments: +# $(1) = library name +# $(2) = library objects +# $(3) = additional dependencies +# $(4) = linker to use +# $(5) = linker options +# $(6) = linker executable +# +define project.target.library.rules.file* + +# $(0) +# $(1) +# $(2) +# $(3) +# $(4) +# $(5) +# $(6) + +$(call library_rule_template,$(1),$(2),$(3),$(4),$(5),$(6)) # end $(0) diff --git a/.make/rules/executable b/.make/rules/executable index 3238462..8aea164 100644 --- a/.make/rules/executable +++ b/.make/rules/executable @@ -9,6 +9,9 @@ # $(1) = path to the executable file # $(2) = paths to the object files # $(3) = additional dependencies +# $(4) = compiler +# $(5) = compiler options +# $(6) = compiler executable # # Returns: # rules for compiling the objects in $(2) into the executable $(1) @@ -17,7 +20,7 @@ # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -executable_rule_template = $(call rule_template,$(1),$(call gcc.compile_example,$(1),$(2),$(linkage)),$(2) $(3),$(dir $(1))) +executable_rule_template = $(call rule_template,$(1),$(call $(4).link,$(2),$(1),$(5),$(6)),$(2) $(3),$(dir $(1))) # Computes the parameters for and evaluates the executable rule template. # @@ -25,9 +28,12 @@ executable_rule_template = $(call rule_template,$(1),$(call gcc.compile_example, # $(1) = executable name # $(2) = executable sources # $(3) = additional dependencies +# $(4) = compiler +# $(5) = compiler options +# $(6) = compiler executable # # Returns: # rules for compiling the objects generated from the sources in $(2) # into the executable named $(1) # -generate_executable_rule = $(call executable_rule_template,$(call to_executable,$(1)),$(call to_object,$(2)),$(3)) +generate_executable_rule = $(call executable_rule_template,$(call to_executable,$(1)),$(call to_object,$(2)),$(3),$(4),$(5),$(6)) diff --git a/.make/rules/libraries b/.make/rules/libraries index 9ab912a..52dc11e 100644 --- a/.make/rules/libraries +++ b/.make/rules/libraries @@ -16,11 +16,14 @@ static_library_rule_template = $(call rule_template,$(1),$(call archiver.create, # $(1) = path to dynamic library # $(2) = list of object files # $(3) = additional dependencies +# $(4) = linker +# $(5) = linker options +# $(6) = linker executable # # Returns: # rules for generating dynamic library $(1) from the objects in $(2) # -dynamic_library_rule_template = $(call rule_template,$(1),$(call compiler.compile_dynamic_library,$(1),$(2)),$(2) $(3),$(dir $(1))) +dynamic_library_rule_template = $(call rule_template,$(1),$(call $(4).link,$(2),$(1),$(5),$(6)),$(2) $(3),$(dir $(1))) # Rule template for libraries corresponding to the current linkage. # @@ -28,6 +31,9 @@ dynamic_library_rule_template = $(call rule_template,$(1),$(call compiler.compil # $(1) = library name # $(2) = list of object files # $(3) = additional dependencies +# $(4) = linker +# $(5) = linker options +# $(6) = linker executable # # Variables: # $(linkage) = linkage type: static | dynamic @@ -35,7 +41,7 @@ dynamic_library_rule_template = $(call rule_template,$(1),$(call compiler.compil # Returns: # rules for generating library $(1) from the objects in $(2) # -library_rule_template = $(call $(linkage)_library_rule_template,$(call as_library,$(1)),$(2),$(3)) +library_rule_template = $(call $(linkage)_library_rule_template,$(call as_library,$(1)),$(2),$(3),$(4),$(5),$(6)) # Evaluates a library rule template for the current linkage. # diff --git a/.make/rules/objects b/.make/rules/objects index 93ec40e..7f219ab 100644 --- a/.make/rules/objects +++ b/.make/rules/objects @@ -10,17 +10,23 @@ # $(2) = path to object file # $(3) = path to dependency data file # $(4) = additional dependencies +# $(5) = compiler +# $(6) = compiler options +# $(7) = compiler executable # # References: # # https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#depdelete # -object_rule_template = $(call rule_template,$(2),$(call compiler.compile_object,$(2),$(1),$(3),$(linkage)),$(1) $(4),$(dir $(2) $(3))) +object_rule_template = $(call rule_template,$(2),$(call $(5).compile,$(1),$(2),$(3),$(6),$(7)),$(1) $(4),$(dir $(2) $(3))) # Computes the parameters for and evaluates the object rule template. # # Arguments: # $(1) = path to source file # $(2) = additional dependencies +# $(3) = compiler +# $(4) = compiler options +# $(5) = compiler executable # -generate_object_rule = $(call object_rule_template,$(1),$(call to_object,$(1)),$(call to_dependency,$(1)),$(2)) +generate_object_rule = $(call object_rule_template,$(1),$(call to_object,$(1)),$(call to_dependency,$(1)),$(2),$(3),$(4),$(5)) diff --git a/make/file b/make/file index c64df86..00cf9c8 100644 --- a/make/file +++ b/make/file @@ -11,17 +11,33 @@ include make/structure liblinux.targets := +liblinux.compiler := $(compiler) +liblinux.compiler.gcc.options := -std=c99 -ffreestanding \ + -Wall -Wextra -Wpedantic \ + -I $(include_directory) \ + -Os \ + $(if $(call equal?,$(linkage),static),-static -fno-PIC,-shared -fPIC) \ + -fno-strict-aliasing -fno-stack-protector + +liblinux.linker := $(compiler) +liblinux.linker.gcc.options := $(if $(call equal?,$(linkage),static),-static -fno-PIC,-shared -fPIC) \ + -Os -fno-strict-aliasing -fno-stack-protector + # System call library liblinux.targets += library library.type := library library.name := linux library.sources := $(call find,$(source_directory),file?) +library.linker.gcc.options := -nostdlib + # Process startup code liblinux.targets += startfiles startfiles.type := object startfiles.sources := $(call find,$(start_architecture_directory),file?) +$(call to_object,$(start_architecture_directory)/_start.S).gcc.options := -P + # GCC linker specification file and wrapper script # Makes it easy to build programs using liblinux gcc_specs_script := $(scripts_directory)/liblinux.specs.sh @@ -54,7 +70,10 @@ liblinux.targets += $(1) $(1).type := executable $(1).sources := $(2) -$(1).dependencies := $(call to_executable,liblinux-gcc) +$(1).dependencies := $(gcc_wrapper) + +$(1).compiler.gcc := $(gcc_wrapper) +$(1).linker.gcc := $(gcc_wrapper) endef From dff5fc1c0d38aa891ef0c470af4aa38a9ddfb89e Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 13 Jul 2019 16:20:30 -0300 Subject: [PATCH 137/153] Removed unused compiler variables and functions These symbols are no longer used after the compiler interface redesign. --- .make/compiler | 45 --------------------------------------------- .make/compilers/gcc | 16 ---------------- 2 files changed, 61 deletions(-) diff --git a/.make/compiler b/.make/compiler index ed0bdab..08c3aa9 100644 --- a/.make/compiler +++ b/.make/compiler @@ -1,46 +1 @@ include .make/compilers/gcc - -default_compiler := gcc -compiler := $(default_compiler) - -compiler_common_options = $($(compiler)_common_options) - -compiler_library_search_options = $($(compiler)_library_directory_option) -compiler_code_generation_options = $($(compiler)_code_generation_options) -compiler_compile_option := $($(compiler)_compile_option) -compiler_shared_library_option := $($(compiler)_shared_library_option) -compiler_nostdlib_option := $($(compiler)_nostdlib_option) -compiler_output_option = $($(compiler)_output_option) -compiler_link_option = $($(compiler)_link_option) - -compiler.options.dependency_data_generation = $(call $(compiler)_dependency_generation_options,$(1),$(2)) - -define compiler.compile_object -$(compiler) \ -$(compiler_common_options) \ -$(call compiler.options.dependency_data_generation,$(3),$(1)) \ -$(compiler_nostdlib_option) \ -$(call compiler_code_generation_options,$(4)) \ -$(call compiler_output_option,$(1)) \ -$(compiler_compile_option) $(2) -endef - -define compiler.compile_startup_object -$(compiler) \ -$(compiler_common_options) \ -$(compiler_nostdlib_option) \ -$(call compiler_output_option,$(1)) \ -$(compiler_compile_option) $(2) -endef - -define compiler.compile_dynamic_library -$(compiler) \ -$(compiler_common_options) \ -$(compiler_nostdlib_option) \ -$(compiler_code_generation_options) \ -$(compiler_shared_library_option) \ -$(call compiler_output_option,$(1)) \ -$(2) -endef - -compiler.generate_dependency_data = $($(compiler).generate_dependency_data) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index 061aa2e..9cb7cbf 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -35,22 +35,6 @@ $(gcc_optimization_options) \ $(gcc_instrumentation_options) endef -# GCC command line generation functions -define gcc.compile_example -$(gcc_wrapper) \ -$(gcc_common_options) \ -$(call gcc_static_option,$(3)) \ -$(call gcc_output_option,$(1)) \ -$(2) -endef - -define gcc.generate_dependency_data -$(gcc) \ -$(gcc_common_options) \ -$(call gcc_dependency_generation_options,$(1),$(3) $(1)) \ -$(2) -endef - redirect_input_to = < $(1) gcc_read_from_standard_input := - gcc_null_input := $(gcc_read_from_standard_input) $(call redirect_input_to,/dev/null) From 5b76405d4cc238a2238d4c3b9e1d34036ddde9a4 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 13 Jul 2019 16:41:09 -0300 Subject: [PATCH 138/153] Rename GCC option variables and functions Now they use a dot to denote the hierarchy of their values. --- .make/compilers/gcc | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index 9cb7cbf..436f420 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -2,28 +2,31 @@ gcc := gcc # GCC option variable and function definitions -gcc_standard_option = -std=$(1) -gcc_library_directory_option = -L$(1) -gcc_include_directory_option = -I $(include_directory) -gcc_compile_option := -c -gcc_preprocess_option := -E +gcc.options.output = -o $(1) +gcc.options.compile := -c +gcc.options.preprocess := -E +gcc.options.dependency_generation = -MD -MF $(1) $(foreach target,$(2),-MT $(target)) +gcc.options.standard = -std=$(1) +gcc.options.directory.include = -I $(1) +gcc.options.directory.library = -L$(1) +gcc.options.include.macros = -imacros $(1) +gcc.options.dump.macro_names := -dN +gcc.redirect_input_to = - < $(1) +gcc.null_input := $(call gcc.redirect_input_to,/dev/null) + gcc_inhibit_linemarkers_option := -P -gcc_include_macros_option = -imacros $(1) -gcc_list_macro_names_option := -dN gcc_shared_library_option := -shared gcc_nostdlib_option := -nostdlib -gcc_output_option = -o $(1) gcc_static_option = $(if $(call equal?,$(1),static),-static) gcc_link_option = -l $(1) gcc_specs_option = -specs=$(1) gcc_code_generation_options = $(if $(call equal?,$(1),static),-fno-PIC,-fPIC) -gcc_dependency_generation_options = -MD -MF $(1) $(foreach target,$(2),-MT $(target)) # Common GCC options -gcc_dialect_options = $(strip $(call gcc_standard_option,$(or $(1),c99)) $(if $(2),-ffreestanding)) +gcc_dialect_options = $(strip $(call gcc.options.standard,$(or $(1),c99)) $(if $(2),-ffreestanding)) gcc_warning_options := -Wall -Wextra -Wpedantic -gcc_preprocessor_options = $(call gcc_include_directory_option,$(include_directory)) $(gcc_inhibit_linemarkers_option) +gcc_preprocessor_options = $(call gcc.options.directory.include,$(include_directory)) $(gcc_inhibit_linemarkers_option) gcc_optimization_options := -Os -fno-strict-aliasing gcc_instrumentation_options := -fno-stack-protector @@ -35,17 +38,13 @@ $(gcc_optimization_options) \ $(gcc_instrumentation_options) endef -redirect_input_to = < $(1) -gcc_read_from_standard_input := - -gcc_null_input := $(gcc_read_from_standard_input) $(call redirect_input_to,/dev/null) - define gcc.list_defined_macros $(gcc) \ $(gcc_common_options) \ -$(gcc_preprocess_option) \ -$(gcc_list_macro_names_option) \ -$(call gcc_include_macros_option,$(1)) \ -$(gcc_null_input) +$(gcc.options.preprocess) \ +$(gcc.options.dump.macro_names) \ +$(call gcc.options.include.macros,$(1)) \ +$(gcc.null_input) endef # Generates a GCC command line that compiles a source file into an object file. @@ -63,9 +62,9 @@ endef define gcc.compile $(or $(5),$(gcc)) \ $(4) \ -$(call gcc_dependency_generation_options,$(3),$(2)) \ -$(call gcc_output_option,$(2)) \ -$(gcc_compile_option) $(1) +$(call gcc.options.dependency_generation,$(3),$(2)) \ +$(call gcc.options.output,$(2)) \ +$(gcc.options.compile) $(1) endef # Generates a GCC command line that links object files. @@ -82,6 +81,6 @@ endef define gcc.link $(or $(4),$(gcc)) \ $(3) \ -$(call gcc_output_option,$(2)) \ +$(call gcc.options.output,$(2)) \ $(1) endef From a5185235de2530eb4f8c11bf57e71b6a3de064ef Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 13 Jul 2019 17:15:54 -0300 Subject: [PATCH 139/153] Delete GCC option variables that are too specific These variables are too specific to be applicable to the build system's compiler interface. They will be provided by the user. --- .make/compilers/gcc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index 436f420..8d4bd0b 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -14,15 +14,6 @@ gcc.options.dump.macro_names := -dN gcc.redirect_input_to = - < $(1) gcc.null_input := $(call gcc.redirect_input_to,/dev/null) -gcc_inhibit_linemarkers_option := -P -gcc_shared_library_option := -shared -gcc_nostdlib_option := -nostdlib -gcc_static_option = $(if $(call equal?,$(1),static),-static) -gcc_link_option = -l $(1) -gcc_specs_option = -specs=$(1) - -gcc_code_generation_options = $(if $(call equal?,$(1),static),-fno-PIC,-fPIC) - # Common GCC options gcc_dialect_options = $(strip $(call gcc.options.standard,$(or $(1),c99)) $(if $(2),-ffreestanding)) gcc_warning_options := -Wall -Wextra -Wpedantic From 58d4bedf0291efd4998f1d981e49c96b23169169 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sat, 13 Jul 2019 17:36:28 -0300 Subject: [PATCH 140/153] Fix system call list generation rules Remove reference to the undefined build_scripts_directory variable. Doesn't make sense to have a scripts directory in the build tree, so the location of the targets is now its root. Directories are now created unconditionally. --- make/system_call_lists | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/make/system_call_lists b/make/system_call_lists index b53b39b..bec5237 100644 --- a/make/system_call_lists +++ b/make/system_call_lists @@ -1,32 +1,32 @@ # System calls available on the system system-calls.available.sh := $(scripts_directory)/system-calls.available.sh -system-calls.available := $(build_scripts_directory)/system-calls.available +system-calls.available := $(build_root_directory)/system-calls.available definitions.h := $(include_liblinux_directory)/definitions.h $(system-calls.available) : $(system-calls.available.sh) $(definitions.h) - $(call ensure_target_directory_exists) + $(call mkdir_p,$(dir $@)) $(call gcc.list_defined_macros,$(definitions.h)) | $< > $@ # System calls implemented in liblinux system-calls.implemented.sh := $(scripts_directory)/system-calls.implemented.sh -system-calls.implemented := $(build_scripts_directory)/system-calls.implemented +system-calls.implemented := $(build_root_directory)/system-calls.implemented liblinux_system_calls := $(basename $(notdir $(wildcard $(include_liblinux_directory)/system_calls/*.h))) $(system-calls.implemented) : $(system-calls.implemented.sh) - $(call ensure_target_directory_exists) + $(call mkdir_p,$(dir $@)) $< $(liblinux_system_calls) > $@ # System calls missing from liblinux system-calls.missing.sh := $(scripts_directory)/system-calls.missing.sh -system-calls.missing := $(build_scripts_directory)/system-calls.missing +system-calls.missing := $(build_root_directory)/system-calls.missing $(system-calls.missing) : $(system-calls.missing.sh) $(system-calls.available) $(system-calls.implemented) - $(call ensure_target_directory_exists) + $(call mkdir_p,$(dir $@)) $< $(system-calls.available) $(system-calls.implemented) > $@ # Phony targets From 53464b54cd1b10fff4b15e7f77dea9883ed0c2bc Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 12 Nov 2019 19:56:30 -0300 Subject: [PATCH 141/153] Generate one include option for each parameter This allows a list of files to be passed, including empty lists. --- .make/compilers/gcc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index 8d4bd0b..9dc1fe1 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -9,7 +9,7 @@ gcc.options.dependency_generation = -MD -MF $(1) $(foreach target,$(2),-MT $(tar gcc.options.standard = -std=$(1) gcc.options.directory.include = -I $(1) gcc.options.directory.library = -L$(1) -gcc.options.include.macros = -imacros $(1) +gcc.options.include.macros = $(foreach file,$(1),-imacros $(file)) gcc.options.dump.macro_names := -dN gcc.redirect_input_to = - < $(1) gcc.null_input := $(call gcc.redirect_input_to,/dev/null) From 66037c69862d0ea3eb09e4eede16562e543d65c1 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 12 Nov 2019 19:59:21 -0300 Subject: [PATCH 142/153] Add new parameter to gcc.list_defined_macros Now the GCC executable can be passed as parameter. --- .make/compilers/gcc | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index 9dc1fe1..5937675 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -29,15 +29,6 @@ $(gcc_optimization_options) \ $(gcc_instrumentation_options) endef -define gcc.list_defined_macros -$(gcc) \ -$(gcc_common_options) \ -$(gcc.options.preprocess) \ -$(gcc.options.dump.macro_names) \ -$(call gcc.options.include.macros,$(1)) \ -$(gcc.null_input) -endef - # Generates a GCC command line that compiles a source file into an object file. # # Arguments: @@ -75,3 +66,23 @@ $(3) \ $(call gcc.options.output,$(2)) \ $(1) endef + +# Generates a GCC command line that lists all defined macros. +# +# Arguments: +# $(1) = files to include +# $(2) = options +# $(3) = GCC executable to use +# +# Returns: +# command line that uses $(3) with the options in $(2) +# to list all macros defined after including the files in $(1) +# +define gcc.list_defined_macros +$(or $(3),$(gcc)) \ +$(gcc.options.preprocess) \ +$(gcc.options.dump.macro_names) \ +$(call gcc.options.include.macros,$(1)) \ +$(2) \ +$(gcc.null_input) +endef From 0ff79dff1151cc288b20260ebda93f286272f281 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 12 Nov 2019 20:05:53 -0300 Subject: [PATCH 143/153] Delete the gcc_common_options variable It is no longer being referenced by any makefile. --- .make/compilers/gcc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index 5937675..a035439 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -21,14 +21,6 @@ gcc_preprocessor_options = $(call gcc.options.directory.include,$(include_direct gcc_optimization_options := -Os -fno-strict-aliasing gcc_instrumentation_options := -fno-stack-protector -define gcc_common_options -$(call gcc_dialect_options,$(C.standard),$(C.freestanding)) \ -$(gcc_warning_options) \ -$(gcc_preprocessor_options) \ -$(gcc_optimization_options) \ -$(gcc_instrumentation_options) -endef - # Generates a GCC command line that compiles a source file into an object file. # # Arguments: From c40797a781ca71e631d7d5fd0ee595c5da7832f1 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 12 Nov 2019 20:08:32 -0300 Subject: [PATCH 144/153] Delete application-specific GCC option variables Optimization and instrumentation options are application-specific. --- .make/compilers/gcc | 3 --- 1 file changed, 3 deletions(-) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index a035439..b3cc200 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -14,12 +14,9 @@ gcc.options.dump.macro_names := -dN gcc.redirect_input_to = - < $(1) gcc.null_input := $(call gcc.redirect_input_to,/dev/null) -# Common GCC options gcc_dialect_options = $(strip $(call gcc.options.standard,$(or $(1),c99)) $(if $(2),-ffreestanding)) gcc_warning_options := -Wall -Wextra -Wpedantic gcc_preprocessor_options = $(call gcc.options.directory.include,$(include_directory)) $(gcc_inhibit_linemarkers_option) -gcc_optimization_options := -Os -fno-strict-aliasing -gcc_instrumentation_options := -fno-stack-protector # Generates a GCC command line that compiles a source file into an object file. # From a2da813b37e1d8300ef4bf989c32fab455447452 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 12 Nov 2019 20:10:31 -0300 Subject: [PATCH 145/153] Improve gcc.compile documentation Make the description of the return value more accurate. --- .make/compilers/gcc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index b3cc200..e3adc38 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -28,7 +28,8 @@ gcc_preprocessor_options = $(call gcc.options.directory.include,$(include_direct # $(5) = GCC executable to use # # Returns: -# command line that compiles $(1) into $(2) using the options in $(4) +# command line that uses $(5) with the options in $(4) +# to compile $(1) into $(2) and emit dependency data to $(3) # define gcc.compile $(or $(5),$(gcc)) \ From ee49804381b6359752d748d5bfae2312fb3451ff Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 12 Nov 2019 20:11:02 -0300 Subject: [PATCH 146/153] Improve gcc.link documentation Make the description of the return value more accurate. --- .make/compilers/gcc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.make/compilers/gcc b/.make/compilers/gcc index e3adc38..fc7717e 100644 --- a/.make/compilers/gcc +++ b/.make/compilers/gcc @@ -48,7 +48,8 @@ endef # $(4) = GCC executable to use # # Returns: -# command line that compiles $(1) into $(2) using the options in $(4) +# command line that uses $(4) with the options in $(3) +# to link $(1) into $(2) # define gcc.link $(or $(4),$(gcc)) \ From f1cb0fae7b6a6e57e23416a49e0cdb46a6eb7937 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 12 Nov 2019 20:34:24 -0300 Subject: [PATCH 147/153] Delete C.freestanding variable It is no longer being referenced by any makefile. --- make/file | 2 -- 1 file changed, 2 deletions(-) diff --git a/make/file b/make/file index 00cf9c8..6d9a5e4 100644 --- a/make/file +++ b/make/file @@ -1,5 +1,3 @@ -C.freestanding := yes - architecture ?= x86_64 linkage ?= static compiler ?= gcc From acd1ad5fad354eb77c79cdd7e98dfcfe15fa3798 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Tue, 12 Nov 2019 22:39:52 -0300 Subject: [PATCH 148/153] Use higher level directory creation function The ensure_target_directory_exists function is easier to understand compared to directory creation commands. --- make/system_call_lists | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/make/system_call_lists b/make/system_call_lists index bec5237..ef2e28a 100644 --- a/make/system_call_lists +++ b/make/system_call_lists @@ -6,7 +6,7 @@ system-calls.available := $(build_root_directory)/system-calls.available definitions.h := $(include_liblinux_directory)/definitions.h $(system-calls.available) : $(system-calls.available.sh) $(definitions.h) - $(call mkdir_p,$(dir $@)) + $(call ensure_target_directory_exists) $(call gcc.list_defined_macros,$(definitions.h)) | $< > $@ # System calls implemented in liblinux @@ -17,7 +17,7 @@ system-calls.implemented := $(build_root_directory)/system-calls.implemented liblinux_system_calls := $(basename $(notdir $(wildcard $(include_liblinux_directory)/system_calls/*.h))) $(system-calls.implemented) : $(system-calls.implemented.sh) - $(call mkdir_p,$(dir $@)) + $(call ensure_target_directory_exists) $< $(liblinux_system_calls) > $@ # System calls missing from liblinux @@ -26,7 +26,7 @@ system-calls.missing.sh := $(scripts_directory)/system-calls.missing.sh system-calls.missing := $(build_root_directory)/system-calls.missing $(system-calls.missing) : $(system-calls.missing.sh) $(system-calls.available) $(system-calls.implemented) - $(call mkdir_p,$(dir $@)) + $(call ensure_target_directory_exists) $< $(system-calls.available) $(system-calls.implemented) > $@ # Phony targets From da45caae709e3533541f290bfb5d80a810696bcd Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 18 Nov 2019 16:25:43 -0300 Subject: [PATCH 149/153] Build up an inverted build stack This eliminates the need to reverse the list later, simplifying the already rather complicated functions. The executable and library targets don't add their outputs to the build stack because their symbolic names are enough to represent the outputs. --- .make/project | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.make/project b/.make/project index 99f1d9d..3711265 100644 --- a/.make/project +++ b/.make/project @@ -42,7 +42,7 @@ endef # $(1) = the project's targets # $(2) = build stack # -project.targets = $(foreach target,$(1),$(call project.target,$(target),$(2) $(target))) +project.targets = $(foreach target,$(1),$(call project.target,$(target),$(target) $(2))) # Generates rules appropriate for the given target's type. # @@ -97,7 +97,7 @@ define project.target.object.rules # $(1) # $(2) -$(foreach source,$($(1).sources),$(call $(0).file,$(source),$(2) $(call to_object,$(source)),$($(1).dependencies))) +$(foreach source,$($(1).sources),$(call $(0).file,$(source),$(call to_object,$(source)) $(2),$($(1).dependencies))) # end $(0) @@ -117,7 +117,7 @@ define project.target.object.rules.file # $(2) # $(3) -$(call $(0)*,$(1),$(2),$(3),$(call resolve.first,$(call reverse,$(2)),compiler)) +$(call $(0)*,$(1),$(2),$(3),$(call resolve.first,$(2),compiler)) # end $(0) @@ -137,7 +137,7 @@ define project.target.object.rules.file* # $(3) # $(4) -$(call $(0)*,$(1),$(3),$(4),$(call resolve.all,$(2),compiler $(4) options),$(call resolve.first,$(call reverse,$(2)),compiler $(4))) +$(call $(0)*,$(1),$(3),$(4),$(call resolve.all,$(2),compiler $(4) options),$(call resolve.first,$(2),compiler $(4))) # end $(0) @@ -214,7 +214,7 @@ define project.target.executable.rules $(call project.target.object.rules,$(1),$(2)) -$(call $(0).file,$(1),$(2),$($(1).sources),$($(1).dependencies),$(call resolve.first,$(call reverse,$(2)),linker)) +$(call $(0).file,$(1),$(2),$($(1).sources),$($(1).dependencies),$(call resolve.first,$(2),linker)) # end $(0) @@ -236,7 +236,7 @@ define project.target.executable.rules.file # $(4) # $(5) -$(call $(0)*,$(1),$(3),$(4),$(5),$(call resolve.all,$(2),linker $(5) options),$(call resolve.first,$(call reverse,$(2)),linker $(5))) +$(call $(0)*,$(1),$(3),$(4),$(5),$(call resolve.all,$(2),linker $(5) options),$(call resolve.first,$(2),linker $(5))) # end $(0) @@ -312,7 +312,7 @@ define project.target.library.rules $(call project.target.object.rules,$(1),$(2)) -$(call $(0).file,$(1),$(2),$($(1).name),$(call to_object,$($(1).sources)),$($(1).dependencies),$(call resolve.first,$(call reverse,$(2)),linker)) +$(call $(0).file,$(1),$(2),$($(1).name),$(call to_object,$($(1).sources)),$($(1).dependencies),$(call resolve.first,$(2),linker)) # end $(0) @@ -338,7 +338,7 @@ define project.target.library.rules.file # $(5) # $(6) -$(call $(0)*,$(3),$(4),$(5),$(6),$(call resolve.all,$(2),linker $(6) options),$(call resolve.first,$(call reverse,$(2)),linker $(6))) +$(call $(0)*,$(3),$(4),$(5),$(6),$(call resolve.all,$(2),linker $(6) options),$(call resolve.first,$(2),linker $(6))) # end $(0) From 92d0c56c7efb0d1b03bea0fe07d7e3dee7c6f132 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 18 Nov 2019 16:47:26 -0300 Subject: [PATCH 150/153] Define the resolve.name.first make function Handle empty namespace lists: just call resolve.name directly. Reimplement resolve.first in terms of the new function. --- .make/functions/variables | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/.make/functions/variables b/.make/functions/variables index 7530c8d..f6755d6 100644 --- a/.make/functions/variables +++ b/.make/functions/variables @@ -47,6 +47,23 @@ defined? = $(call not,$(call undefined?,$(1))) # resolve.name = $(subst $(space),$(or $(2),.),$(strip $(1))) +# Resolves the name of the first defined variable in a list of namespaces. +# A namespace is the first component of a composite variable name. +# +# Arguments: +# $(1) = list of namespaces in order +# $(2) = variable to resolve +# $(3) = separator +# +# Defaults: +# $(3) = . +# +# Returns: +# the name of the first defined variable $(1) in the $(2) namespaces +# +resolve.name.first* = $(if $(call defined?,$(4)),$(4),$(call resolve.name.first,$(call rest,$(1)),$(2),$(3))) +resolve.name.first = $(if $(1),$(call $(0)*,$(1),$(2),$(3),$(call resolve.name,$(firstword $(1)) $(2),$(3))),$(call resolve.name,$(2),$(3))) + # Resolves a composite variable name and retrieves its value. # # Arguments: @@ -91,5 +108,4 @@ resolve.all = $(strip $(foreach ns,$(1),$(call resolve.value,$(ns) $(2),$(3)))) # Returns: # the value of the first defined variable $(1) in the $(2) namespaces # -resolve.first* = $(if $(call defined?,$(4)),$($(4)),$(call resolve.first,$(call rest,$(1)),$(2),$(3))) -resolve.first = $(if $(1),$(call $(0)*,$(1),$(2),$(3),$(call resolve.name,$(firstword $(1)) $(2),$(3)))) +resolve.first = $($(call resolve.name.first,$(1),$(2),$(3))) From 4c7fce28364156dbb2ff30af37f96ad499eacb15 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 18 Nov 2019 16:48:52 -0300 Subject: [PATCH 151/153] Rename resolve.first to resolve.value.first This makes the function names more consistent. --- .make/functions/variables | 16 ++++++++-------- .make/project | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.make/functions/variables b/.make/functions/variables index f6755d6..b2f8603 100644 --- a/.make/functions/variables +++ b/.make/functions/variables @@ -78,11 +78,11 @@ resolve.name.first = $(if $(1),$(call $(0)*,$(1),$(2),$(3),$(call resolve.name, # resolve.value = $($(call resolve.name,$(1),$(2))) -# Resolves a variable in a list of namespaces and retrieves their values. +# Resolves the value of the first defined variable in a list of namespaces. # A namespace is the first component of a composite variable name. # # Arguments: -# $(1) = list of namespaces +# $(1) = list of namespaces in order # $(2) = variable to resolve # $(3) = separator # @@ -90,15 +90,15 @@ resolve.value = $($(call resolve.name,$(1),$(2))) # $(3) = . # # Returns: -# the values bound to the variable $(1) inside all the namespaces in $(2) +# the value of the first defined variable $(1) in the $(2) namespaces # -resolve.all = $(strip $(foreach ns,$(1),$(call resolve.value,$(ns) $(2),$(3)))) +resolve.value.first = $($(call resolve.name.first,$(1),$(2),$(3))) -# Resolves the value of the first defined variable in a list of namespaces. +# Resolves a variable in a list of namespaces and retrieves their values. # A namespace is the first component of a composite variable name. # # Arguments: -# $(1) = list of namespaces in order +# $(1) = list of namespaces # $(2) = variable to resolve # $(3) = separator # @@ -106,6 +106,6 @@ resolve.all = $(strip $(foreach ns,$(1),$(call resolve.value,$(ns) $(2),$(3)))) # $(3) = . # # Returns: -# the value of the first defined variable $(1) in the $(2) namespaces +# the values bound to the variable $(1) inside all the namespaces in $(2) # -resolve.first = $($(call resolve.name.first,$(1),$(2),$(3))) +resolve.all = $(strip $(foreach ns,$(1),$(call resolve.value,$(ns) $(2),$(3)))) diff --git a/.make/project b/.make/project index 3711265..856c2ef 100644 --- a/.make/project +++ b/.make/project @@ -117,7 +117,7 @@ define project.target.object.rules.file # $(2) # $(3) -$(call $(0)*,$(1),$(2),$(3),$(call resolve.first,$(2),compiler)) +$(call $(0)*,$(1),$(2),$(3),$(call resolve.value.first,$(2),compiler)) # end $(0) @@ -137,7 +137,7 @@ define project.target.object.rules.file* # $(3) # $(4) -$(call $(0)*,$(1),$(3),$(4),$(call resolve.all,$(2),compiler $(4) options),$(call resolve.first,$(2),compiler $(4))) +$(call $(0)*,$(1),$(3),$(4),$(call resolve.all,$(2),compiler $(4) options),$(call resolve.value.first,$(2),compiler $(4))) # end $(0) @@ -214,7 +214,7 @@ define project.target.executable.rules $(call project.target.object.rules,$(1),$(2)) -$(call $(0).file,$(1),$(2),$($(1).sources),$($(1).dependencies),$(call resolve.first,$(2),linker)) +$(call $(0).file,$(1),$(2),$($(1).sources),$($(1).dependencies),$(call resolve.value.first,$(2),linker)) # end $(0) @@ -236,7 +236,7 @@ define project.target.executable.rules.file # $(4) # $(5) -$(call $(0)*,$(1),$(3),$(4),$(5),$(call resolve.all,$(2),linker $(5) options),$(call resolve.first,$(2),linker $(5))) +$(call $(0)*,$(1),$(3),$(4),$(5),$(call resolve.all,$(2),linker $(5) options),$(call resolve.value.first,$(2),linker $(5))) # end $(0) @@ -312,7 +312,7 @@ define project.target.library.rules $(call project.target.object.rules,$(1),$(2)) -$(call $(0).file,$(1),$(2),$($(1).name),$(call to_object,$($(1).sources)),$($(1).dependencies),$(call resolve.first,$(2),linker)) +$(call $(0).file,$(1),$(2),$($(1).name),$(call to_object,$($(1).sources)),$($(1).dependencies),$(call resolve.value.first,$(2),linker)) # end $(0) @@ -338,7 +338,7 @@ define project.target.library.rules.file # $(5) # $(6) -$(call $(0)*,$(3),$(4),$(5),$(6),$(call resolve.all,$(2),linker $(6) options),$(call resolve.first,$(2),linker $(6))) +$(call $(0)*,$(3),$(4),$(5),$(6),$(call resolve.all,$(2),linker $(6) options),$(call resolve.value.first,$(2),linker $(6))) # end $(0) From b4f61926c2e8f3c437e863a5d2d73235c17c4065 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 18 Nov 2019 18:29:02 -0300 Subject: [PATCH 152/153] Define resolve.stack+ and resolve.stack- functions These functions resolve variables in caller-provided namespaces as well as an implicit global namespace. One merges the results while the other does not. Only the values in the global namespace are meant to be inheritable. Other namespaces override each other according to their order. --- .make/functions/variables | 35 +++++++++++++++++++++++++++++++++++ .make/project | 12 ++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/.make/functions/variables b/.make/functions/variables index b2f8603..95bbd78 100644 --- a/.make/functions/variables +++ b/.make/functions/variables @@ -94,6 +94,41 @@ resolve.value = $($(call resolve.name,$(1),$(2))) # resolve.value.first = $($(call resolve.name.first,$(1),$(2),$(3))) +# Resolves the value of the first defined variable in a list of namespaces +# in addition to the value of the variable in the global namespace. +# A namespace is the first component of a composite variable name. +# +# Arguments: +# $(1) = list of namespaces +# $(2) = variable to resolve +# $(3) = separator +# +# Defaults: +# $(3) = . +# +# Returns: +# the the value of $(1) in the global namespace +# and the value the first defined $(1) variable inside all $(2) namespaces +# +resolve.stack+ = $(strip $(call resolve.value,global $(2),$(3)) $(call resolve.value.first,$(1),$(2),$(3))) + +# Resolves the value of the first defined variable in a list of namespaces and the global namespace. +# A namespace is the first component of a composite variable name. +# +# Arguments: +# $(1) = list of namespaces +# $(2) = variable to resolve +# $(3) = separator +# +# Defaults: +# $(3) = . +# +# Returns: +# the value the first defined $(1) variable inside all $(2) namespaces +# or the value of $(1) in the global namespace +# +resolve.stack- = $(call resolve.value.first,$(1) global,$(2),$(3)) + # Resolves a variable in a list of namespaces and retrieves their values. # A namespace is the first component of a composite variable name. # diff --git a/.make/project b/.make/project index 856c2ef..cc495ce 100644 --- a/.make/project +++ b/.make/project @@ -117,7 +117,7 @@ define project.target.object.rules.file # $(2) # $(3) -$(call $(0)*,$(1),$(2),$(3),$(call resolve.value.first,$(2),compiler)) +$(call $(0)*,$(1),$(2),$(3),$(call resolve.stack-,$(2),compiler)) # end $(0) @@ -137,7 +137,7 @@ define project.target.object.rules.file* # $(3) # $(4) -$(call $(0)*,$(1),$(3),$(4),$(call resolve.all,$(2),compiler $(4) options),$(call resolve.value.first,$(2),compiler $(4))) +$(call $(0)*,$(1),$(3),$(4),$(call resolve.stack+,$(2),compiler $(4) options),$(call resolve.stack-,$(2),compiler $(4))) # end $(0) @@ -214,7 +214,7 @@ define project.target.executable.rules $(call project.target.object.rules,$(1),$(2)) -$(call $(0).file,$(1),$(2),$($(1).sources),$($(1).dependencies),$(call resolve.value.first,$(2),linker)) +$(call $(0).file,$(1),$(2),$($(1).sources),$($(1).dependencies),$(call resolve.stack-,$(2),linker)) # end $(0) @@ -236,7 +236,7 @@ define project.target.executable.rules.file # $(4) # $(5) -$(call $(0)*,$(1),$(3),$(4),$(5),$(call resolve.all,$(2),linker $(5) options),$(call resolve.value.first,$(2),linker $(5))) +$(call $(0)*,$(1),$(3),$(4),$(5),$(call resolve.stack+,$(2),linker $(5) options),$(call resolve.stack-,$(2),linker $(5))) # end $(0) @@ -312,7 +312,7 @@ define project.target.library.rules $(call project.target.object.rules,$(1),$(2)) -$(call $(0).file,$(1),$(2),$($(1).name),$(call to_object,$($(1).sources)),$($(1).dependencies),$(call resolve.value.first,$(2),linker)) +$(call $(0).file,$(1),$(2),$($(1).name),$(call to_object,$($(1).sources)),$($(1).dependencies),$(call resolve.stack-,$(2),linker)) # end $(0) @@ -338,7 +338,7 @@ define project.target.library.rules.file # $(5) # $(6) -$(call $(0)*,$(3),$(4),$(5),$(6),$(call resolve.all,$(2),linker $(6) options),$(call resolve.value.first,$(2),linker $(6))) +$(call $(0)*,$(3),$(4),$(5),$(6),$(call resolve.stack+,$(2),linker $(6) options),$(call resolve.stack-,$(2),linker $(6))) # end $(0) From cb3221092e54267b3f856a9fb0cc383f79647ab8 Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Mon, 18 Nov 2019 18:35:11 -0300 Subject: [PATCH 153/153] Adjust make/file due to new stack semantics Now only values present in the global namespace are inherited. --- make/file | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/make/file b/make/file index 6d9a5e4..9eb50d6 100644 --- a/make/file +++ b/make/file @@ -4,22 +4,24 @@ compiler ?= gcc configuration := $(architecture) $(linkage) $(compiler) +option.PIC = $(if $(call equal?,$(linkage),static),-fno-PIC,-fPIC) +option.linkage = $(if $(call equal?,$(linkage),static),-static,-shared) + # Project file system structure include make/structure +global.compiler.gcc.options := -std=c99 -ffreestanding \ + -Wall -Wextra -Wpedantic \ + -I $(include_directory) \ + -Os -fno-strict-aliasing -fno-stack-protector + liblinux.targets := liblinux.compiler := $(compiler) -liblinux.compiler.gcc.options := -std=c99 -ffreestanding \ - -Wall -Wextra -Wpedantic \ - -I $(include_directory) \ - -Os \ - $(if $(call equal?,$(linkage),static),-static -fno-PIC,-shared -fPIC) \ - -fno-strict-aliasing -fno-stack-protector +liblinux.compiler.gcc.options := $(option.PIC) liblinux.linker := $(compiler) -liblinux.linker.gcc.options := $(if $(call equal?,$(linkage),static),-static -fno-PIC,-shared -fPIC) \ - -Os -fno-strict-aliasing -fno-stack-protector +liblinux.linker.gcc.options := $(option.linkage) # System call library liblinux.targets += library @@ -27,14 +29,17 @@ library.type := library library.name := linux library.sources := $(call find,$(source_directory),file?) -library.linker.gcc.options := -nostdlib +library.linker.gcc.options := $(option.linkage) -nostdlib # Process startup code liblinux.targets += startfiles startfiles.type := object startfiles.sources := $(call find,$(start_architecture_directory),file?) -$(call to_object,$(start_architecture_directory)/_start.S).gcc.options := -P +startfiles.compiler.gcc.options := -fno-PIC +startfiles.linker.gcc.options := -static + +$(call to_object,$(start_architecture_directory)/_start.S).gcc.options := $(startfiles.compiler.gcc.options) -P # GCC linker specification file and wrapper script # Makes it easy to build programs using liblinux