diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-03-01 19:15:29 -0500 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-03-01 19:15:29 -0500 |
commit | c83d2b58e1776982a7ce45009fb373ec5702c521 (patch) | |
tree | 5e6cae25f11846392936895f2c2a8ca019c21bbb | |
parent | 47004c9601147b4c5c55c2bd6401bda8b6be0406 (diff) |
improve HACKING documentation
-rw-r--r-- | COPYING | 2 | ||||
-rw-r--r-- | HACKING/build-system.md | 24 | ||||
-rw-r--r-- | HACKING/code-quality.md (renamed from HACKING.md) | 121 | ||||
-rw-r--r-- | HACKING/code-style.md | 62 | ||||
-rw-r--r-- | HACKING/contributing.md | 26 | ||||
-rw-r--r-- | HACKING/licensing.md | 19 | ||||
-rw-r--r-- | HACKING/testing.md | 18 | ||||
-rw-r--r-- | automake.head.mk | 2 | ||||
-rw-r--r-- | automake.txt | 131 |
9 files changed, 226 insertions, 179 deletions
@@ -6,4 +6,4 @@ and license statement, each file contains a "License:" line to make searching easy. Full copies of the GNU General Public License versions 2 and 3 are -included as `COPYING-GPLv2` and `COPYING-GPLv3`, respectively.
\ No newline at end of file +included as `COPYING-GPLv2` and `COPYING-GPLv3`, respectively. diff --git a/HACKING/build-system.md b/HACKING/build-system.md new file mode 100644 index 0000000..93770cc --- /dev/null +++ b/HACKING/build-system.md @@ -0,0 +1,24 @@ +The build system is built around an automake-like system for GNU Make +that I wrote. It is documented in `automake.txt`. It provides all of +the standard targets and such; you tell it what to do by setting a +series of `am_whatever` variables. I'm just going to call it +"automake" here. + +I also hook into non-exposed parts of automake with a couple of +`_am_whatever` variables. Hopefully I will come up with good ways to +expose the needed functionality in the future. + +There are a couple of variables that get automatically set from git. +This happens by `include`ing a hidden makefile that sets them; if +`$(topsrcdir)/.git` exists, it knows to use git to generate it; +otherwise it expects the file to exist: + +| variable | file | +|--------------------+----------------------------------------| +| srcfiles | $(srcdir)/.srcfiles.mk | +| LIBRETOOLS_VERSION | $(topsrcdir)/.srcversion-libretools.mk | +| LIBRETOOLS_COMMIT | $(topsrcdir)/.srcversion-libretools.mk | +| DEVTOOLS_VERSION | $(topsrcdir)/.srcversion-devtools.mk | +| DEVTOOLS_COMMIT | $(topsrcdir)/.srcversion-devtools.mk | + +`srcfiles` basically becomes `am_src_files`. diff --git a/HACKING.md b/HACKING/code-quality.md index ee5cd65..a520ce5 100644 --- a/HACKING.md +++ b/HACKING/code-quality.md @@ -1,56 +1,10 @@ -This document is a little all over the place--I've been working on it -for a while, but I keep refactoring it as I move pieces of it into man -pages and whatnot. It's mostly a brain dump, sorry. - -There are three parts to this; procedures, "content" guidelines and -"style" guidelines. The style guidelines are less strict; as long as -things are consistent at the file-level, I'm pretty happy. - -Contributing -============ - -I'd love to have your patches! Code should be hackable; if you want -to modify something, but can't figure out how: 1) ping me for help, 2) -it probably means the code was too complicated in the first place. - -Patches should be sent to <dev@lists.parabolagnulinux.org>; please put -"[PATCH]" and "libretools" in the subject line. If you have commit -access, but want me to look over it first, feel free to create a new -branch in git, and I will notice it. Try to avoid pushing to the -"master" branch unless it's a trivial change; it makes it easier to -review things; though I *will* look over every commit before I do a -release, so don't think you can sneak something in :) - -I'd love to discuss possible changes on IRC (I'm lukeshu), either on -irc.freenode.net#parabola or in personal messages. My account may be -online even if I'm not; I will eventually see your it, I do a search -for mentions of "luke" on #parabola every time I get on. - -Testing -======= - -Please write unit tests for new things. Tests can be run with `make -check`, which just runs `./testenv roundup` in the `test/` directory. -Relatedly, you need the `roundup` tool to run the tests. `./testenv` -can be given `--no-network` and/or `--no-sudo` to dissable tests that -require those things. Make can be made to pass those things in by -setting `TESTENVFLAGS`. If you don't dissable either, I *strongly* -recommend setting TMPDIR to somewhere on a btrfs partition before -running the tests; otherwise the chroot tests will take forever. I -mean, they already take long on btrfs, but without it... _dang_. - -I also recommend having the `haveged` daemon running. That's good -general advice, but also: some of the tests make GPG keys, this -"should" take on the order of 1 second, but can take several minutes -if you don't have `haveged` running. - Code content ============ Be aware of the `librelib(7)` library suite, which lives `src/lib`. It is a suite of Bash libraries that will help you out. Most of the people looking at the libretools code are familiar with the `messages` -part of it, which actually contains a much of utility routines, not +part of it, which actually contains a bunch of utility routines, not just message printing. There is also a library for dealing with `blacklist.txt`, and one for loading configuration files and PKGBUILDs. These are common tasks, but are tricky to handle @@ -178,76 +132,3 @@ My brief rules of thumb: while read line; do ... done < <(prog) - - -Style guidelines -================ - -Unless you have a good reason, use `[[ ... ]]` instead of `[ ... ]`; -they work similarly, but `[[ ... ]]` is sometimes more readable (fine, -rarely, but never less), and is harder to make mistakes with quoting, -because it is syntactic magic, as opposed to `[ ... ]` which is an -executable which just happens to be implemented as a builtin. - -Use a litteral tab for indent. When indenting line-wrapped text, such -as that for `prose`, do it like this: (» indicates tab, · indicates -space) - - func() { - » prose "This is the first line. This paragraph is going to be - » ·······wrapped." - } - -The `; then` and `; do` should go on the same line as -`if`/`elif`/`for`/`while`. Also, there is no space before the `;`. - -Prefer the `for VAR in LIST` syntax over the `for ((init; cond; inc))` -syntax, when possible. For example (heh, `for` example): - - local i - for (( i = 1 ; i <= 10 ; i++ )); do - -should be - - local i - for i in {1..10}; do - -Of course, if the upper bound is a variable, the C-like syntax is -the better option, as otherwise you would have to use `seq` (calling -an external), or `eval` (gross, easy to mess up royally). - -Indent comments like you would code; don't leave them at the beginning -of the line. Example: - - for item in "${list[@]}"; do - if [[ $item == foo ]]; then - # BAD - foobar - fi - if [[ $item == bar ]]; then - # GOOD - barbaz - fi - done - -Fauno, I'm sorry. But I don't know how you can read your own code :P. - -Some people argue in favor of the useless use of cat, because data -should flow from left to right. However, the input redirection -doesn't have to go on the right side of a command: - - cat file | program # useless use of cat - program < file # data flows right to left - < file program # just right - -Copyright statements should look like - - # Copyright (C) YEARS NAME <EMAIL> - -for most code, for 3rd-party code that has been imported, indent it a -bit: - - # Copyright (C) YEARS NAME <EMAIL> - -Always put a line with `# License:` specifying the license of that -file. diff --git a/HACKING/code-style.md b/HACKING/code-style.md new file mode 100644 index 0000000..077bc49 --- /dev/null +++ b/HACKING/code-style.md @@ -0,0 +1,62 @@ +The style guidelines aren't terribly strict. As long as things are +consistent per-file, I'm pretty happy. + +Style guidelines +================ + +Unless you have a good reason, use `[[ ... ]]` instead of `[ ... ]`; +they work similarly, but `[[ ... ]]` is sometimes more readable (fine, +rarely, but never less), and is harder to make mistakes with quoting, +because it is syntactic magic, as opposed to `[ ... ]` which is an +executable which just happens to be implemented as a builtin. + +Use a litteral tab for indent. When indenting line-wrapped text, such +as that for `prose`, do it like this: (» indicates tab, · indicates +space) + + func() { + » prose "This is the first line. This paragraph is going to be + » ·······wrapped." + } + +The `; then` and `; do` should go on the same line as +`if`/`elif`/`for`/`while`. Also, there is no space before the `;`. + +Prefer the `for VAR in LIST` syntax over the `for ((init; cond; inc))` +syntax, when possible. For example (heh, `for` example): + + local i + for (( i = 1 ; i <= 10 ; i++ )); do + +should be + + local i + for i in {1..10}; do + +Of course, if the upper bound is a variable, the C-like syntax is +the better option, as otherwise you would have to use `seq` (calling +an external), or `eval` (gross, easy to mess up royally). + +Indent comments like you would code; don't leave them at the beginning +of the line. Example: + + for item in "${list[@]}"; do + if [[ $item == foo ]]; then + # BAD + foobar + fi + if [[ $item == bar ]]; then + # GOOD + barbaz + fi + done + +Fauno, I'm sorry. But I don't know how you can read your own code :P. + +Some people argue in favor of the useless use of cat, because data +should flow from left to right. However, the input redirection +doesn't have to go on the right side of a command: + + cat file | program # useless use of cat + program < file # data flows right to left + < file program # just right diff --git a/HACKING/contributing.md b/HACKING/contributing.md new file mode 100644 index 0000000..65066b5 --- /dev/null +++ b/HACKING/contributing.md @@ -0,0 +1,26 @@ +Contributing +============ + +I'd love to have your patches! Code should be hackable; if you want +to modify something, but can't figure out how: 1) ping me for help, 2) +it probably means the code was too complicated in the first place. + +Patches should be sent to <dev@lists.parabolagnulinux.org>; please put +"[PATCH]" and "libretools" in the subject line. If you have commit +access, but want me to look over it first, feel free to create a new +branch in git, and I will notice it. Try to avoid pushing to the +"master" branch unless it's a trivial change; it makes it easier to +review things; though I *will* look over every commit before I do a +release, so don't think you can sneak something in :) + +Be sure to make sure to follow the licensing requirements in +`HACKING/licensing.md` + +I'd love to discuss possible changes on IRC (I'm lukeshu), either on +irc.freenode.net#parabola or in personal messages. My account may be +online even if I'm not; I will eventually see your message, I do a +search for mentions of "luke" on #parabola every time I get on. + +Please write unit tests for new functionality. Or old functionality. +Please write unit tests! See `HACKING/testing.md` for details on +testing. diff --git a/HACKING/licensing.md b/HACKING/licensing.md new file mode 100644 index 0000000..6d17e31 --- /dev/null +++ b/HACKING/licensing.md @@ -0,0 +1,19 @@ +We don't require copyright assignment or any fancy paperwork! Just +make sure you specify the license and include a copyright statement +with your name and the current year. + +New code should (please) be licensed GPLv2+. I say v2 instead of v3 +because some code from Arch is GPLv2 (no "or any later version"), and +having to worry about which programs can be combined is a huge pain. + +Copyright statements should look like + + # Copyright (C) YEARS NAME <EMAIL> + +for most code, for 3rd-party code that has been imported, indent it a +bit: + + # Copyright (C) YEARS NAME <EMAIL> + +Always put a line with `# License:` specifying the license of that +file. diff --git a/HACKING/testing.md b/HACKING/testing.md new file mode 100644 index 0000000..8dee485 --- /dev/null +++ b/HACKING/testing.md @@ -0,0 +1,18 @@ +Testing +======= + +Please write unit tests for new things. Tests can be run with `make +check`, which just runs `./testenv roundup` in the `test/` directory. +Relatedly, you need the `roundup` (the `sh-roundup` package on +Parabola) tool to run the tests. `./testenv` can be given +`--no-network` and/or `--no-sudo` to dissable tests that require those +things. Make can be made to pass those things in by setting +`TESTENVFLAGS`. If you don't dissable either, I *strongly* recommend +setting TMPDIR to somewhere on a btrfs partition before running the +tests; otherwise the chroot tests will take forever. I mean, they +already take long on btrfs, but without it... _dang_. + +I also recommend having the `haveged` daemon running. That's good +general advice, but also: some of the tests make GPG keys, this +"should" take on the order of 1 second, but can take several minutes +if you don't have `haveged` running. diff --git a/automake.head.mk b/automake.head.mk index a3c90fd..ad7154c 100644 --- a/automake.head.mk +++ b/automake.head.mk @@ -39,7 +39,7 @@ endif _am_included_makefiles := $(_am_included_makefiles) $(call _am_path,$(outdir)/Makefile) -## Empty variables for use by the module +## Empty variables for use by each Makefile $(_am)subdirs = $(_am)depdirs = diff --git a/automake.txt b/automake.txt index 307b321..22a0b84 100644 --- a/automake.txt +++ b/automake.txt @@ -7,14 +7,13 @@ automake.{head,tail}.mk Makefiles and how to use them, kinda. I wrote a "clone" of automake. I say clone, because it works differently. Yeah, I need a new name for it. -Anyway, how to use it: +High-level overview +------------------- In each source directory, you write a `Makefile`, very similarly to if you were writing for plain GNU Make, with -_am_phony = build install uninstall mostlyclean clean distclean maintainer-clean check - - + # adjust the number of `../` segments as appropriate include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk include $(topsrcdir)/automake.head.mk @@ -22,63 +21,81 @@ _am_phony = build install uninstall mostlyclean clean distclean maintainer-clean include $(topsrcdir)/automake.tail.mk -Write your own `common.each.mk` that gets included after the body of -your Makefile for each Makefile. - -Write your own `common.once.mk` that gets included once after -everything else has been parsed. - -There are several commands that generate files; simply record what -they the list of files in their output to the following variables: - -| Variable | Command | Description | Relative to | -|-----------+--------------+-----------------------------------+-------------| -| src_files | emacs | Files that the developer writes | srcdir | -| gen_files | ??? | Files the developer compiles | srcdir | -| cfg_files | ./configure | Users' compile-time configuration | outdir | -| out_files | make all | Files the user compiles | outdir | -| sys_files | make install | Files the user installs | DESTDIR | - -In addition, there are - - subdirs : A list of other directories containing Makefiles that - contain or generate files that are dependencies of - targets in this directory. They are not necesarily - actually subdirectories of this directory in the - filesystem. - - clean_files : A list of things to `rm` in addition to - `$(out_files)` when you run `make clean`. (Example: - `*.o`). - - slow_files : A list of things in `$(out_files)` that (as an - exception) should _not_ be deleted when you run `make - mostlyclean`. - -Each directory containing a Makefile is a "module". The module name -is one of 4 things (with / replaced with _ in all cases): - - `all` - - $(realpath --relative-to=. $dir_name) - - dep-top - - dep-$(realpath --relative-to=$(topoutdir) $dir_name) - -The dep-* options are only used if that directory is not a child of -the current directory. +Write your own `common.{each,once}.{head,tail}.mk` files that get +included: + - `common.once.head.mk`: before parsing any of your Makefiles + - `common.each.head.mk`: before parsing each of your Makefiles + - `common.each.tail.mk`: after parsing each of your Makefiles + - `common.each.tail.mk`: after parsing all of your Makefiles Here is a table of all of the .PHONY targets that automake takes care of for you: -| this | and this | are aliases for this | which is just a case of this | -|------+------------------+----------------------+------------------------------| -| all | build | build-all | build-$(module) | -| | install | install-all | install-$(module) | -| | uninstall | uninstall-all | uninstall-$(module) | -| | mostlyclean | mostlyclean-all | mostlyclean-$(module) | -| | clean | clean-all | clean-$(module) | -| | distclean | distclean-all | distclean-$(module) | -| | maintainer-clean | maintainer-clean-all | maintainer-clean-$(module) | -| | check | check-all | check-$(module) | -| | | | dist | +| this | and this | are aliases for this | +|------+------------------+--------------------------------------------------------| +| all | build | $(outdir)/build | +| | install | $(outdir)/install | +| | uninstall | $(outdir)/uninstall | +| | mostlyclean | $(outdir)/mostlyclean | +| | clean | $(outdir)/clean | +| | distclean | $(outdir)/distclean | +| | maintainer-clean | $(outdir)/maintainer-clean | +| | check | $(outdir)/check (not implemented for you) | +| | dist | $(topoutdir)/$(PACKAGE)-$(VERSION).tar.gz (not .PHONY) | + +You are responsible for implementing the `$(outdir)/check` target in +each of your Makefiles. + +Telling automake about your program +----------------------------------- + +You tell automake what to do for you by setting some variables. They +are all prefixed with `am_`; this prefix may be changed by editing the +`_am` variable at the top of `automake.head.mk`. + +There are several commands that generate files; simply record the list +of files that each command generates as the following variable +variables: + +| Variable | Create Command | Delete Command | Description | Relative to | +|--------------+----------------+-----------------------------+-----------------------------------+-------------| +| am_src_files | emacs | rm -rf . | Files that the developer writes | srcdir | +| am_gen_files | ??? | make maintainer-clean | Files the developer compiles | srcdir | +| am_cfg_files | ./configure | make distclean | Users' compile-time configuration | outdir | +| am_out_files | make all | make mostlyclean/make clean | Files the user compiles | outdir | +| am_sys_files | make install | make uninstall | Files the user installs | DESTDIR | + +In addition, there are two more variables that control not how files +are created, but how they are deleted: + +| Variable | Affected command | Description | Relative to | +|----------------+------------------+------------------------------------------------+-------------| +| am_clean_files | make clean | A list of things to `rm` in addition to the | outdir | +| | | files in `$(am_out_files)`. (Example: `*.o`) | | +|----------------+------------------+------------------------------------------------+-------------| +| am_slow_files | make mostlyclean | A list of things that (as an exception) should | outdir | +| | | _not_ be deleted. (otherwise, `mostlyclean` | | +| | | is the same as `clean`) | | + +Finally, there are two variables that express the relationships +between directories: + +| Variable | Description | +|------------+---------------------------------------------------------| +| am_subdirs | A list of other directories (containing Makefiles) that | +| | may be considered "children" of this | +| | directory/Makefile; building a phony target in this | +| | directory should also build it in the subdirectory. | +| | They are not necesarily actually subdirectories of this | +| | directory in the filesystem. | +|------------+---------------------------------------------------------| +| am_depdirs | A list of other directories (containing Makefiles) that | +| | contain or generate files that are dependencies of | +| | targets in this directory. They are not necesarily | +| | actually subdirectories of this directory in the | +| | filesystem. Except for files that are dependencies of | +| | files in this directory, things in the dependency | +| | directory will not be built. | ---- Copyright (C) 2016 Luke Shumaker |