mirror of
https://https.git.savannah.gnu.org/git/gnulib.git
synced 2026-04-28 06:33:36 +00:00
867 lines
28 KiB
Plaintext
867 lines
28 KiB
Plaintext
Information for GNU Gnulib maintainers and contributors
|
|
*******************************************************
|
|
|
|
Using git
|
|
=========
|
|
|
|
* We don't use topic branches. Changes are usually small enough that
|
|
they can be committed directly to the master branch, after appropriate
|
|
testing.
|
|
|
|
* We maintain stable branches, though, as described in the documentation:
|
|
https://www.gnu.org/software/gnulib/manual/html_node/Stable-Branches.html
|
|
When backporting a commit to a stable branch of the last year, be sure
|
|
to update the copyright year of each modified file (since we don't run
|
|
"make update-copyright" on the stable branches).
|
|
|
|
* We use a linear git history — no merges. To work in this setting, it's
|
|
recommended that you configure git with 'git config pull.rebase = true'.
|
|
|
|
* Before pushing a commit, it is highly recommended that you review it in
|
|
its entirety. The easiest ways to do so are
|
|
* to run
|
|
$ git format-patch -1
|
|
and then read the patch in an editor that has syntax-colouring of patch
|
|
files, or
|
|
* to run
|
|
$ gitk
|
|
|
|
* We update the ChangeLog by hand. The commit message is usually identical
|
|
to the ChangeLog entry, with the date and author line removed, with
|
|
the leading tabs removed, and with a blank line after the commit's
|
|
summary line.
|
|
In order to work efficiently with ChangeLog files, it is recommended that
|
|
you configure git to use the git-merge-changelog driver; see the instructions
|
|
in the lib/git-merge-changelog.c file.
|
|
Note: This driver reasonably keeps the ChangeLog entries together; however,
|
|
it does not always keep them in the order you would desire. For example,
|
|
when you had prepared a commit, you try to "git push" it but that fails due
|
|
to someone else's commit that came earlier, what you need to do is:
|
|
1. $ git pull
|
|
2. Verify that your ChangeLog entry is still the top-most one.
|
|
3. If it is not, then edit ChangeLog to move it to the top, and
|
|
$ git commit --amend ChangeLog
|
|
4. $ gitk
|
|
5. $ git push
|
|
|
|
* When you commit a contributor's patch, please
|
|
- add a reasonable ChangeLog entry in the usual style (meaningful
|
|
summary line and detailed change list),
|
|
- as the date of the ChangeLog entry, use the current date (cf.
|
|
https://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html ).
|
|
- if the contribution is so small that it does not require a
|
|
copyright assignment (cf.
|
|
https://www.gnu.org/prep/maintain/html_node/Legally-Significant.html )
|
|
add a line:
|
|
Copyright-paperwork-exempt: Yes
|
|
- use the 'git commit' option --author="Contributor Name <email@address>"
|
|
|
|
|
|
License Notices
|
|
===============
|
|
|
|
In *.m4 files, use a notice like this:
|
|
dnl Copyright (C) YEARS Free Software Foundation, Inc.
|
|
dnl This file is free software; the Free Software Foundation
|
|
dnl gives unlimited permission to copy and/or distribute it,
|
|
dnl with or without modifications, as long as this notice is preserved.
|
|
dnl This file is offered as-is, without any warranty.
|
|
|
|
In lib/, tests/, build-aux/ files, except those that are shared with glibc,
|
|
use the license notices from etc/license-notices/ . This avoids gratuitous
|
|
differences in wording, as well misunderstandings when a license notice
|
|
would say "This program ...".
|
|
|
|
|
|
Test Suite
|
|
==========
|
|
|
|
When adding a module, add a unit test module as well. This is our best
|
|
chance to catch portability problems.
|
|
|
|
A unit test can have many sub-tests. Try to make the sub-tests independent
|
|
of each other, so that it becomes easy to disable some sub-tests by enclosing
|
|
them in #if 0 ... #endif.
|
|
|
|
The main() function's exit code meaning is:
|
|
- 0: PASS
|
|
- 77: SKIP; you should print the reason why the test is skipped.
|
|
- 99: ERROR, i.e. test framework error
|
|
- any other exit code < 126: FAIL
|
|
|
|
In tests that #include "macros.h" and use the ASSERT macro:
|
|
The main() function should, before it returns 0 (for PASS) or 77 (for SKIP)
|
|
test the value of test_exit_status and return that instead. So:
|
|
- not
|
|
return 0;
|
|
but instead
|
|
return test_exit_status;
|
|
- not
|
|
return result; // where result can be 0 or 1
|
|
but instead
|
|
return (result ? result : test_exit_status);
|
|
- not
|
|
fputs ("Skipping test: <reason>\n", stderr);
|
|
return 77;
|
|
but instead
|
|
if (test_exit_status != EXIT_SUCCESS)
|
|
return test_exit_status;
|
|
fputs ("Skipping test: <reason>\n", stderr);
|
|
return 77;
|
|
Only at the beginning of the main() function, when ASSERT has not yet been
|
|
invoked, we know that test_exit_status must be zero and can therefore write
|
|
fputs ("Skipping test: <reason>\n", stderr);
|
|
return 77;
|
|
directly.
|
|
|
|
|
|
Maintaining high quality
|
|
========================
|
|
|
|
It is a good idea to occasionally create a testdir of all of Gnulib:
|
|
$ rm -rf ../testdir-all; ./gnulib-tool --create-testdir --dir=../testdir-all --with-c++-tests --without-privileged-tests `./all-modules`
|
|
and test this directory on various platforms:
|
|
- Linux/glibc systems,
|
|
- Linux/musl systems,
|
|
- macOS,
|
|
- FreeBSD,
|
|
- NetBSD,
|
|
- OpenBSD,
|
|
- AIX,
|
|
- Solaris 10 and 11,
|
|
- Cygwin,
|
|
- Haiku,
|
|
- Android,
|
|
- and other platforms of your choice.
|
|
|
|
There are two continuous integrations that regularly perform this testing:
|
|
* On a Linux/glibc system only:
|
|
https://gitlab.com/gnulib/gnulib-ci
|
|
This one will catch only the most blatant mistakes.
|
|
* On many platforms:
|
|
https://github.com/gnu-gnulib/ci-testdir-check/actions
|
|
This one runs on many platforms, currently (as of June 2024):
|
|
- Ubuntu GNU/Linux 22.04
|
|
- CentOS GNU/Linux 7
|
|
- Alpine Linux
|
|
- macOS 11, 12, 13 (all x86_64)
|
|
- macOS 14 (arm64)
|
|
- FreeBSD 14.0
|
|
- NetBSD 10.0
|
|
- OpenBSD 7.5
|
|
- Solaris 11.4
|
|
- Solaris 11 OmniOS
|
|
- Cygwin 3.3.6 (32 bit) and 3.5.3 (64 bit)
|
|
- mingw (32 bit and 64 bit)
|
|
- MSVC (32 bit and 64 bit)
|
|
and also
|
|
- on Ubuntu GNU/Linux 22.04 with clang's UBSAN and ASAN sanitizers.
|
|
This one catches real portability problems.
|
|
Note that the following platforms are not covered and thus still require
|
|
occasional manual testing:
|
|
- AIX
|
|
- Solaris 10
|
|
- Haiku
|
|
- Android
|
|
- and other platforms of your choice.
|
|
|
|
|
|
Coding Style
|
|
============
|
|
|
|
For C source code:
|
|
|
|
* Follow the portability guidelines
|
|
https://www.gnu.org/software/gnulib/manual/html_node/Portability-guidelines.html
|
|
|
|
* Use mixed declarations and statements, as appropriate. (This is supported
|
|
since C99.)
|
|
|
|
* Note: You can't put a label before a declaration, such as in
|
|
retry:
|
|
int foo = ...;
|
|
This is supported only in C23 or newer. Instead, add an empty statement:
|
|
retry: ;
|
|
int foo = ...;
|
|
Similarly, you can't put a declaration immediately after a case label, such
|
|
as in
|
|
case 1:
|
|
int foo = ...;
|
|
...
|
|
break;
|
|
Again, this is supported only in C23 or newer. Instead, use a sub-block:
|
|
case 1:
|
|
{
|
|
int foo = ...;
|
|
...
|
|
}
|
|
break;
|
|
|
|
* In function definitions and blocks, the pre-C99 style "declare all variables
|
|
upfront" is discouraged.
|
|
Instead, the following style elements are encouraged (for local non-static
|
|
variables):
|
|
- Move the declaration of a variable to its initialization.
|
|
- Reduce the scope of variables:
|
|
. If a variable is only used in a sub-block, declare it in that sub-block.
|
|
. If a variable is only used in several sub-blocks and has a separate
|
|
initialization in each of the sub-blocks, declare it in each of these
|
|
sub-blocks. It's actually several independent variables.
|
|
. If a variable is only used in a small part of a function definition or
|
|
block (say, 1/3 of it or less), you may surround that part (including
|
|
the variable's initialization) with braces, so that it becomes clear
|
|
that the variable is not used in the rest of the function / block.
|
|
- Usually, try to declare and initialize variables right when they are
|
|
needed for the first time, not several computation steps before.
|
|
The rationale is:
|
|
- It follows the general principle "Put related things close together."
|
|
- A function with 3 blocks that each has 4 variables is easier to
|
|
understand than a function that has 12 variables, and where the
|
|
reader has to find out which variable is used where.
|
|
- Variables may represent state, and it is the state and the control flow
|
|
that contribute to the complexity of a function.
|
|
Only static variables are better kept declared upfront in a function or block.
|
|
|
|
|
|
Acceptable use of LLM generated code
|
|
====================================
|
|
|
|
General-purpose LLMs as well as LLMs specialized for software programming
|
|
can produce ready-to-use and, in many cases, actually working code.
|
|
|
|
We need to avoid two problems with that:
|
|
|
|
* Copyright and license issue: An LLM may regurgitate a piece of copyrighted
|
|
code without the copyright header, thus violating the code's license.
|
|
(Most code licenses require that the copyright header remains intact when
|
|
the code is copied or becomes the basis of derivative works.)
|
|
|
|
* Maintainability issues: Such generated code has initially not been
|
|
reviewed by a human programmer. It is often greater in size than what a
|
|
careful programmer would write. Sometimes it also lacks comments.
|
|
People who use "vibe coding" often also observe that the code is of
|
|
lower quality.
|
|
Where software in general can be qualified as for long-term use vs.
|
|
short-term use, vibe coding tends to be more suitable for short-term used
|
|
software.
|
|
|
|
To this end:
|
|
|
|
1) Code included in this package that comes from a single LLM prompt
|
|
must be limited in size: it must be at most 5 lines long.
|
|
|
|
2) As a submitter, you assert that you have reviewed such code that you
|
|
submit.
|
|
|
|
Rule 1 guarantees that the LLM generated code size is smaller than the
|
|
"legally significant for copyright purposes" threshold, see
|
|
https://www.gnu.org/prep/maintain/html_node/Legally-Significant.html
|
|
|
|
Rule 2 encourages you to not submit unreviewed garbage.
|
|
|
|
|
|
Warning Options
|
|
===============
|
|
|
|
For packages that use Gnulib, we recommend to use the 'warnings' or
|
|
'manywarnings' module, as documented in
|
|
https://www.gnu.org/software/gnulib/manual/html_node/warnings.html
|
|
https://www.gnu.org/software/gnulib/manual/html_node/manywarnings.html
|
|
|
|
When building Gnulib testdirs, e.g. when preparing a Gnulib patch,
|
|
there are three possible approaches:
|
|
|
|
* The simplest approach, which warns about the most common mistakes, is to
|
|
use GCC's -Wall option, both for C and C++ compilation units. Just set
|
|
$ ./configure CPPFLAGS="-Wall"
|
|
$ make
|
|
You should generally fix all compiler warnings that you see from this
|
|
approach.
|
|
|
|
* If you are developing on a glibc system and have GCC version 15 binaries
|
|
available, here's a recipe that will find more mistakes, but is nearly
|
|
as easy to use. Here, different warning options are needed for C and
|
|
for C++:
|
|
$ WARN_GCC15=`echo '
|
|
-fanalyzer
|
|
-Wall
|
|
-Warith-conversion
|
|
-Wcast-align=strict
|
|
-Wdate-time
|
|
-Wduplicated-cond
|
|
-Wextra
|
|
-Wflex-array-member-not-at-end
|
|
-Wformat-signedness
|
|
-Winit-self
|
|
-Winvalid-pch
|
|
-Wlogical-op
|
|
-Wmaybe-musttail-local-addr
|
|
-Wmissing-include-dirs
|
|
-Wopenmp-simd
|
|
-Woverlength-strings
|
|
-Wpacked
|
|
-Wpointer-arith
|
|
-Wstrict-overflow
|
|
-Wsuggest-final-methods
|
|
-Wsuggest-final-types
|
|
-Wsync-nand
|
|
-Wsystem-headers
|
|
-Wtrampolines
|
|
-Wuninitialized
|
|
-Wunknown-pragmas
|
|
-Wunsafe-loop-optimizations
|
|
-Wvariadic-macros
|
|
-Wvector-operation-performance
|
|
-Wwrite-strings
|
|
-Warray-bounds=2
|
|
-Wattribute-alias=2
|
|
-Wformat-overflow=2
|
|
-Wformat-truncation=2
|
|
-Wshift-overflow=2
|
|
-Wunused-const-variable=2
|
|
-Wvla-larger-than=4031
|
|
-Wno-empty-body
|
|
-Wno-analyzer-allocation-size
|
|
-Wno-analyzer-fd-double-close
|
|
-Wno-analyzer-double-fclose
|
|
-Wno-analyzer-double-free
|
|
-Wno-analyzer-fd-leak
|
|
-Wno-analyzer-fd-use-after-close
|
|
-Wno-analyzer-fd-use-without-check
|
|
-Wno-analyzer-free-of-non-heap
|
|
-Wno-analyzer-malloc-leak
|
|
-Wno-analyzer-mismatching-deallocation
|
|
-Wno-analyzer-null-argument
|
|
-Wno-analyzer-null-dereference
|
|
-Wno-analyzer-out-of-bounds
|
|
-Wno-analyzer-possible-null-argument
|
|
-Wno-analyzer-possible-null-dereference
|
|
-Wno-analyzer-use-after-free
|
|
-Wno-analyzer-use-of-pointer-in-stale-stack-frame
|
|
-Wno-analyzer-use-of-uninitialized-value
|
|
-Wno-analyzer-va-arg-type-mismatch
|
|
-Wno-attribute-warning
|
|
-Wno-cast-align
|
|
-Wno-clobbered
|
|
-Wno-dangling-pointer
|
|
-Wno-format
|
|
-Wno-implicit-fallthrough
|
|
-Wno-maybe-uninitialized
|
|
-Wno-missing-field-initializers
|
|
-Wno-restrict
|
|
-Wno-sign-compare
|
|
-Wno-switch
|
|
-Wno-type-limits
|
|
-Wno-unused-parameter
|
|
' | tr -d '\n' | sed -e 's/ */ /g'`
|
|
$ WARN_CFLAGS_GCC15="$WARN_GCC15 -Wmissing-variable-declarations -Wnested-externs -Wshadow=local -Wno-discarded-qualifiers"
|
|
$ WARN_CXXFLAGS_GCC15="$WARN_GCC15 -Wno-cpp"
|
|
$ ./configure CFLAGS="-O2 -g $WARN_CFLAGS_GCC15" CXXFLAGS="-O2 -g $WARN_CXXFLAGS_GCC15"
|
|
$ make
|
|
You should generally fix all compiler warnings that you see from this
|
|
approach, or report when this approach produced a pointless warning
|
|
(so that we can fix the value of WARN_GCC15 above).
|
|
|
|
* If you are developing on a glibc system and have GCC version 15 binaries
|
|
available: Here's a recipe that will find even more mistakes, but it
|
|
requires that you are willing to filter out and ignore pointless warnings.
|
|
$ WARN_GCC15=`echo '
|
|
-fanalyzer
|
|
-Wall
|
|
-Warith-conversion
|
|
-Wcast-align=strict
|
|
-Wdate-time
|
|
-Wduplicated-cond
|
|
-Wextra
|
|
-Wflex-array-member-not-at-end
|
|
-Wformat-signedness
|
|
-Winit-self
|
|
-Winvalid-pch
|
|
-Wlogical-op
|
|
-Wmaybe-musttail-local-addr
|
|
-Wmissing-include-dirs
|
|
-Wnull-dereference
|
|
-Wopenmp-simd
|
|
-Woverlength-strings
|
|
-Wpacked
|
|
-Wpointer-arith
|
|
-Wstrict-overflow
|
|
-Wsuggest-attribute=format
|
|
-Wsuggest-final-methods
|
|
-Wsuggest-final-types
|
|
-Wsync-nand
|
|
-Wsystem-headers
|
|
-Wtrampolines
|
|
-Wuninitialized
|
|
-Wunknown-pragmas
|
|
-Wunsafe-loop-optimizations
|
|
-Wvariadic-macros
|
|
-Wvector-operation-performance
|
|
-Wwrite-strings
|
|
-Warray-bounds=2
|
|
-Wattribute-alias=2
|
|
-Wformat-overflow=2
|
|
-Wformat=2
|
|
-Wformat-truncation=2
|
|
-Wimplicit-fallthrough=5
|
|
-Wshift-overflow=2
|
|
-Wunused-const-variable=2
|
|
-Wvla-larger-than=4031
|
|
-Wno-empty-body
|
|
-Wno-analyzer-double-fclose
|
|
-Wno-analyzer-double-free
|
|
-Wno-analyzer-free-of-non-heap
|
|
-Wno-analyzer-malloc-leak
|
|
-Wno-analyzer-null-argument
|
|
-Wno-analyzer-null-dereference
|
|
-Wno-analyzer-use-after-free
|
|
-Wno-attribute-warning
|
|
-Wno-cast-align
|
|
-Wno-clobbered
|
|
-Wno-format-nonliteral
|
|
-Wno-sign-compare
|
|
-Wno-type-limits
|
|
-Wno-unused-parameter
|
|
' | tr -d '\n' | sed -e 's/ */ /g'`
|
|
$ WARN_CFLAGS_GCC15="$WARN_GCC15 -Wmissing-variable-declarations -Wnested-externs -Wshadow=local"
|
|
$ WARN_CXXFLAGS_GCC15="$WARN_GCC15 -Wno-cpp"
|
|
$ ./configure CFLAGS="-O2 -g $WARN_CFLAGS_GCC15" CXXFLAGS="-O2 -g $WARN_CXXFLAGS_GCC15"
|
|
$ make
|
|
With this approach, use your own judgement whether to fix warnings
|
|
arising from your new code or not.
|
|
Do *not* submit patches to silence warnings from existing code:
|
|
- For these warnings, often the cure will be worse than the disease.
|
|
- Some of the warnings are false positives. Rather than silencing
|
|
these warnings, we prefer to report them in the GCC bug tracker
|
|
and wait until they are fixed in a future GCC release.
|
|
|
|
Similarly, for clang version 20 you can use the following recipe, that uses
|
|
selected warning options from
|
|
https://releases.llvm.org/20.1.0/tools/clang/docs/DiagnosticsReference.html :
|
|
$ WARN_CLANG20=`echo '
|
|
-Wall
|
|
-Wanon-enum-enum-conversion
|
|
-Warc-repeated-use-of-weak
|
|
-Warray-bounds-pointer-arithmetic
|
|
-Warray-parameter
|
|
-Watomic-properties
|
|
-Wauto-decl-extensions
|
|
-Wbinary-literal
|
|
-Wbit-int-extension
|
|
-Wbitfield-enum-conversion
|
|
-Wbitwise-op-parentheses
|
|
-Wbool-operation
|
|
-Wc++-compat
|
|
-Wc23-compat
|
|
-Wc23-extensions
|
|
-Wc2x-compat
|
|
-Wc2x-extensions
|
|
-Wc23-extensions
|
|
-Wc99-compat
|
|
-Wc99-designator
|
|
-Wc99-extensions
|
|
-Wcalled-once-parameter
|
|
-Wcast-function-type
|
|
-Wchar-subscripts
|
|
-Wcomment
|
|
-Wcompletion-handler
|
|
-Wcomplex-component-init
|
|
-Wcompound-token-split
|
|
-Wconsumed
|
|
-Wconversion
|
|
-Wcstring-format-directive
|
|
-Wcuda-compat
|
|
-Wdate-time
|
|
-Wdelimited-escape-sequence-extension
|
|
-Wdeprecated
|
|
-Wdeprecated-dynamic-exception-spec
|
|
-Wdeprecated-implementations
|
|
-Wdeprecated-this-capture
|
|
-Wdeprecated-writable-strings
|
|
-Wdirect-ivar-access
|
|
-Wdocumentation
|
|
-Wdocumentation-deprecated-sync
|
|
-Wdocumentation-html
|
|
-Wdocumentation-pedantic
|
|
-Wdocumentation-unknown-command
|
|
-Wdollar-in-identifier-extension
|
|
-Wduplicate-decl-specifier
|
|
-Wduplicate-enum
|
|
-Wduplicate-method-arg
|
|
-Wduplicate-method-match
|
|
-Wdynamic-exception-spec
|
|
-Wembedded-directive
|
|
-Wempty-init-stmt
|
|
-Wempty-translation-unit
|
|
-Wenum-compare-conditional
|
|
-Wenum-conversion
|
|
-Wenum-enum-conversion
|
|
-Wenum-float-conversion
|
|
-Wexit-time-destructors
|
|
-Wexpansion-to-defined
|
|
-Wexplicit-ownership-type
|
|
-Wextra
|
|
-Wextra-semi
|
|
-Wflexible-array-extensions
|
|
-Wfloat-overflow-conversion
|
|
-Wfloat-zero-conversion
|
|
-Wfor-loop-analysis
|
|
-Wformat
|
|
-Wformat-pedantic
|
|
-Wformat-type-confusion
|
|
-Wformat=2
|
|
-Wfour-char-constants
|
|
-Wframe-address
|
|
-Wfuse-ld-path
|
|
-Wfuture-attribute-extensions
|
|
-Wgcc-compat
|
|
-Wgnu
|
|
-Wgnu-anonymous-struct
|
|
-Wgnu-auto-type
|
|
-Wgnu-case-range
|
|
-Wgnu-complex-integer
|
|
-Wgnu-compound-literal-initializer
|
|
-Wgnu-conditional-omitted-operand
|
|
-Wgnu-designator
|
|
-Wgnu-empty-initializer
|
|
-Wgnu-empty-struct
|
|
-Wgnu-flexible-array-initializer
|
|
-Wgnu-flexible-array-union-member
|
|
-Wgnu-folding-constant
|
|
-Wgnu-imaginary-constant
|
|
-Wgnu-label-as-value
|
|
-Wgnu-line-marker
|
|
-Wgnu-null-pointer-arithmetic
|
|
-Wgnu-offsetof-extensions
|
|
-Wgnu-pointer-arith
|
|
-Wgnu-redeclared-enum
|
|
-Wgnu-statement-expression
|
|
-Wgnu-statement-expression-from-macro-expansion
|
|
-Wgnu-union-cast
|
|
-Wgnu-zero-line-directive
|
|
-Wgnu-zero-variadic-macro-arguments
|
|
-Wheader-hygiene
|
|
-Widiomatic-parentheses
|
|
-Wignored-qualifiers
|
|
-Wimplicit
|
|
-Wimplicit-fallthrough
|
|
-Wimplicit-fallthrough-per-function
|
|
-Wimplicit-function-declaration
|
|
-Wimplicit-int
|
|
-Wimplicit-retain-self
|
|
-Wimport-preprocessor-directive-pedantic
|
|
-Wincomplete-module
|
|
-Winconsistent-missing-destructor-override
|
|
-Winfinite-recursion
|
|
-Wint-in-bool-context
|
|
-Winvalid-or-nonexistent-directory
|
|
-Winvalid-utf8
|
|
-Wkeyword-macro
|
|
-Wlanguage-extension-token
|
|
-Wlocal-type-template-args
|
|
-Wlogical-op-parentheses
|
|
-Wlong-long
|
|
-Wloop-analysis
|
|
-Wmain
|
|
-Wmax-tokens
|
|
-Wmethod-signatures
|
|
-Wmicrosoft
|
|
-Wmicrosoft-anon-tag
|
|
-Wmicrosoft-charize
|
|
-Wmicrosoft-comment-paste
|
|
-Wmicrosoft-cpp-macro
|
|
-Wmicrosoft-end-of-file
|
|
-Wmicrosoft-enum-value
|
|
-Wmicrosoft-exception-spec
|
|
-Wmicrosoft-fixed-enum
|
|
-Wmicrosoft-flexible-array
|
|
-Wmicrosoft-redeclare-static
|
|
-Wmisleading-indentation
|
|
-Wmismatched-tags
|
|
-Wmissing-braces
|
|
-Wmissing-method-return-type
|
|
-Wmost
|
|
-Wmove
|
|
-Wnested-anon-types
|
|
-Wnewline-eof
|
|
-Wnon-gcc
|
|
-Wnon-modular-include-in-framework-module
|
|
-Wnon-modular-include-in-module
|
|
-Wnon-virtual-dtor
|
|
-Wnonportable-system-include-path
|
|
-Wnull-pointer-arithmetic
|
|
-Wnull-pointer-subtraction
|
|
-Wnullability-extension
|
|
-Wnullable-to-nonnull-conversion
|
|
-Wopenmp
|
|
-Wover-aligned
|
|
-Woverlength-strings
|
|
-Woverloaded-virtual
|
|
-Woverriding-method-mismatch
|
|
-Wpacked
|
|
-Wpacked-non-pod
|
|
-Wparentheses
|
|
-Wpedantic
|
|
-Wpedantic-core-features
|
|
-Wpessimizing-move
|
|
-Wpointer-arith
|
|
-Wpoison-system-directories
|
|
-Wpragma-pack
|
|
-Wpragma-pack-suspicious-include
|
|
-Wpragmas
|
|
-Wpre-c11-compat
|
|
-Wpre-c23-compat
|
|
-Wpre-c2x-compat
|
|
-Wpre-c2y-compat
|
|
-Wpre-openmp-51-compat
|
|
-Wprofile-instr-missing
|
|
-Wquoted-include-in-framework-header
|
|
-Wrange-loop-analysis
|
|
-Wrange-loop-bind-reference
|
|
-Wrange-loop-construct
|
|
-Wreceiver-forward-class
|
|
-Wredundant-move
|
|
-Wredundant-parens
|
|
-Wreorder
|
|
-Wreorder-ctor
|
|
-Wreserved-attribute-identifier
|
|
-Wreserved-user-defined-literal
|
|
-Wretained-language-linkage
|
|
-Wselector
|
|
-Wselector-type-mismatch
|
|
-Wself-assign
|
|
-Wself-assign-overloaded
|
|
-Wself-move
|
|
-Wsemicolon-before-method-body
|
|
-Wshadow-all
|
|
-Wshadow-field
|
|
-Wshadow-field-in-constructor
|
|
-Wshadow-field-in-constructor-modified
|
|
-Wshadow-uncaptured-local
|
|
-Wshift-sign-overflow
|
|
-Wsigned-enum-bitfield
|
|
-Wsometimes-uninitialized
|
|
-Wsource-uses-openacc
|
|
-Wsource-uses-openmp
|
|
-Wspir-compat
|
|
-Wstatic-in-inline
|
|
-Wstrict-potentially-direct-selector
|
|
-Wstrict-selector-match
|
|
-Wstring-concatenation
|
|
-Wstring-conversion
|
|
-Wsuggest-destructor-override
|
|
-Wsuggest-override
|
|
-Wsuper-class-method-mismatch
|
|
-Wtautological-bitwise-compare
|
|
-Wtautological-compare
|
|
-Wtautological-constant-in-range-compare
|
|
-Wtautological-negation-compare
|
|
-Wtautological-overlap-compare
|
|
-Wtautological-type-limit-compare
|
|
-Wtautological-unsigned-char-zero-compare
|
|
-Wtautological-unsigned-enum-zero-compare
|
|
-Wtautological-unsigned-zero-compare
|
|
-Wtautological-value-range-compare
|
|
-Wthread-safety
|
|
-Wthread-safety-analysis
|
|
-Wthread-safety-attributes
|
|
-Wthread-safety-beta
|
|
-Wthread-safety-negative
|
|
-Wthread-safety-precise
|
|
-Wthread-safety-reference
|
|
-Wthread-safety-verbose
|
|
-Wtype-limits
|
|
-Wunaligned-access
|
|
-Wundeclared-selector
|
|
-Wundef-prefix
|
|
-Wundefined-func-template
|
|
-Wundefined-internal-type
|
|
-Wundefined-reinterpret-cast
|
|
-Wunguarded-availability
|
|
-Wuninitialized
|
|
-Wuninitialized-const-reference
|
|
-Wunknown-pragmas
|
|
-Wunnamed-type-template-args
|
|
-Wunneeded-internal-declaration
|
|
-Wunneeded-member-function
|
|
-Wunreachable-code-fallthrough
|
|
-Wunreachable-code-loop-increment
|
|
-Wunsupported-dll-base-class-template
|
|
-Wunused
|
|
-Wunused-but-set-parameter
|
|
-Wunused-but-set-variable
|
|
-Wunused-const-variable
|
|
-Wunused-exception-parameter
|
|
-Wunused-function
|
|
-Wunused-label
|
|
-Wunused-lambda-capture
|
|
-Wunused-local-typedef
|
|
-Wunused-member-function
|
|
-Wunused-private-field
|
|
-Wunused-property-ivar
|
|
-Wunused-template
|
|
-Wunused-variable
|
|
-Wvariadic-macros
|
|
-Wvector-conversion
|
|
-Wvla-cxx-extension
|
|
-Wweak-template-vtables
|
|
-Wweak-vtables
|
|
-Wzero-length-array
|
|
-Wno-bitwise-instead-of-logical
|
|
-Wno-c11-extensions
|
|
-Wno-cast-function-type-strict
|
|
-Wno-float-conversion
|
|
-Wno-format-nonliteral
|
|
-Wno-gnu-include-next
|
|
-Wno-implicit-float-conversion
|
|
-Wno-implicit-int-conversion
|
|
-Wno-implicit-int-float-conversion
|
|
-Wno-include-next-absolute-path
|
|
-Wno-missing-field-initializers
|
|
-Wno-reserved-macro-identifier
|
|
-Wno-shadow
|
|
-Wno-shorten-64-to-32
|
|
-Wno-sign-compare
|
|
-Wno-sign-conversion
|
|
-Wno-strict-prototypes
|
|
-Wno-switch
|
|
-Wno-unused-parameter
|
|
-Wno-tautological-constant-out-of-range-compare
|
|
-Wno-tautological-type-limit-compare
|
|
-Wno-tautological-unsigned-zero-compare
|
|
-Wno-tautological-value-range-compare
|
|
-Wno-unused-command-line-argument
|
|
-Wno-user-defined-warnings
|
|
' | tr -d '\n' | sed -e 's/ */ /g'`
|
|
$ ./configure CFLAGS="-O2 -g $WARN_CLANG20" CXXFLAGS="-O2 -g $WARN_CLANG20"
|
|
$ make
|
|
Again, use your own judgement to determine whether to fix or ignore a
|
|
specific warning.
|
|
|
|
|
|
Maintaining link dependencies
|
|
=============================
|
|
|
|
Each module has a section "Link:", that contains the linker options that
|
|
a program, that makes use of the module, needs to use, in order to avoid
|
|
a link error. Unless empty, this field contains one or more variable
|
|
references, because linker options are platform dependent. A gnulib-tool
|
|
invocation lists these linker options to the package maintainer, so that
|
|
they can make use of these options in the *_LDFLAGS in their package's
|
|
Makefile.am.
|
|
|
|
Of course, the unit tests uses these linker options.
|
|
|
|
Often the link dependencies for module 'foo' follows this naming
|
|
convention: $(FOO_LIB). For example, there are variables references
|
|
$(MBRTOWC_LIB) $(SETLOCALE_LIB).
|
|
|
|
Typically, when you make a code change in a module and accordingly
|
|
define a variable for its linker options in the corresponding *.m4 file,
|
|
you also need to update the linker options of all modules that depend
|
|
on it:
|
|
$ ./gnulib-tool --extract-dependents foo
|
|
and the linker options of all modules that depend on these, etc.:
|
|
$ ./gnulib-tool --extract-recursive-dependents foo
|
|
|
|
The use of a variable per module avoids the need for an avalanche of
|
|
changes.
|
|
|
|
When you notice a link error of a program, you typically fix it in three
|
|
steps:
|
|
1. Ask "Which library does the program need to link with?"
|
|
You answer this by consulting documentation and man pages, as well
|
|
as by use of "nm --dynamic /lib/libxyz.so".
|
|
2. Ask "From which autoconf variable do I get this library option?"
|
|
You answer this by searching the *LIB* values in config.status:
|
|
$ grep LIB config.status
|
|
3. Finally you add a reference to that variable to the *_LIB variable
|
|
of your module. Or, if your module does not have such a variable
|
|
so far, you introduce such a variable and make sure to update all
|
|
dependents to make use of it (see above).
|
|
|
|
|
|
|
|
Information for gnulib-tool maintenance
|
|
***************************************
|
|
|
|
Running the unit tests
|
|
======================
|
|
|
|
The unit tests of gnulib-tool reside in the maint-tools repository, that is a
|
|
satellite repository of the main gnulib repository. Instructions how to obtain
|
|
it are in https://savannah.gnu.org/git/?group=gnulib .
|
|
|
|
To run the unit tests of gnulib-tool.sh:
|
|
$ cd maint-tools/gnulib-tool-tests/
|
|
$ GNULIB_TOOL_IMPL=sh ./test-all.sh
|
|
|
|
To run the unit tests of gnulib-tool.py:
|
|
$ cd maint-tools/gnulib-tool-tests/
|
|
$ GNULIB_TOOL_IMPL=py ./test-all.sh
|
|
|
|
It is *mandatory* that you run the test suite before pushing any change to
|
|
gnulib-tool.sh or gnulib-tool.py! If you fail to do so, and your change contains
|
|
a bug, it will start to affect users immediately.
|
|
|
|
|
|
Debugging the Python implementation of gnulib-tool
|
|
==================================================
|
|
|
|
With Eclipse and PyDev as IDE
|
|
-----------------------------
|
|
|
|
* Download and configuration:
|
|
- Eclipse IDE from https://www.eclipse.org/downloads/packages/
|
|
(either the build for Java or for C/C++ should work fine;
|
|
either use the Eclipse Installer program at the top of the page,
|
|
or one of the individual download links below).
|
|
- PyDev from https://www.pydev.org/download.html
|
|
section "Install as Plugin".
|
|
(Don't use LiClipse, since the license costs money.)
|
|
- Follow https://www.pydev.org/manual_101_install.html,
|
|
replacing http://www.pydev.org/updates
|
|
with https://www.pydev.org/updates
|
|
- Once installed, restart the IDE.
|
|
- Window > Preferences > PyDev > Interpreters > Python Interpreter:
|
|
New > path: /usr/bin/python3
|
|
- Window > Preferences > PyDev > Editor > Code Analysis:
|
|
Others > Redefinition of builtin symbols: Ignore
|
|
|
|
* Create a project:
|
|
Let GNULIB_DIR be my gnulib checkout.
|
|
- File > New > Project... > PyDev > PyDev Project. Call it 'gnulib-tool'.
|
|
Note that this is a project inside the Eclipse workspace, so far
|
|
unrelated to the GNULIB_DIR.
|
|
- Popup menu > New > Link to Existing Source
|
|
Name: gnulib
|
|
Path: <GNULIB_DIR>
|
|
|
|
* Create a run configuration:
|
|
- Run > Run Configurations... > Python Run
|
|
Popup menu > New configuration
|
|
Name: gnulib-tool.py
|
|
Main > Project: gnulib-tool
|
|
Main > Main Module: ${workspace_loc:gnulib-tool/gnulib/.gnulib-tool.py}
|
|
Arguments > Program arguments: --help
|
|
- Test it: Run this configuration.
|
|
|
|
* Create a debug configuration:
|
|
- Run > Debug Configurations... > gnulib-tool.py
|
|
Popup menu > Duplicate
|
|
- In the duplicate, set
|
|
Arguments > Working directory: /tmp/oath-toolkit/lib
|
|
Arguments > Program arguments: --add-import
|
|
|
|
* Debug it:
|
|
- Open GLImport.py.
|
|
- On the left-hand border of this editor, do "Add breakpoint".
|
|
- Run > Debug Configurations... > pick the duplicate. Press Debug.
|
|
|
|
|
|
Maintaining high quality
|
|
========================
|
|
|
|
There is a continuous integration of gnulib-tool.py that runs the unit tests,
|
|
at https://gitlab.com/gnulib/gnulib-tool-ci/ .
|