windows-once: Improve comments.
[gnulib.git] / HACKING
blob34c3adf033eb9f9349078f1a515189efa0a8dcaf
1 Information for GNU Gnulib maintainers and contributors
2 *******************************************************
4 Using git
5 =========
7 * We don't use topic branches.  Changes are usually small enough that
8   they can be committed directly to the master branch, after appropriate
9   testing.
11 * We maintain stable branches, though, as described in the documentation:
12   https://www.gnu.org/software/gnulib/manual/html_node/Stable-Branches.html
13   When backporting a commit to a stable branch of the last year, be sure
14   to update the copyright year of each modified file (since we don't run
15   "make update-copyright" on the stable branches).
17 * We use a linear git history — no merges. To work in this setting, it's
18   recommended that you configure git with 'git config pull.rebase = true'.
20 * Before pushing a commit, it is highly recommended that you review it in
21   its entirety. The easiest ways to do so are
22     * to run
23         $ git format-patch -1
24       and then read the patch in an editor that has syntax-colouring of patch
25       files, or
26     * to run
27         $ gitk
29 * We update the ChangeLog by hand.  The commit message is usually identical
30   to the ChangeLog entry, with the date and author line removed, with
31   the leading tabs removed, and with a blank line after the commit's
32   summary line.
33   In order to work efficiently with ChangeLog files, it is recommended that
34   you configure git to use the git-merge-changelog driver; see the instructions
35   in the lib/git-merge-changelog.c file.
36   Note: This driver reasonably keeps the ChangeLog entries together; however,
37   it does not always keep them in the order you would desire. For example,
38   when you had prepared a commit, you try to "git push" it but that fails due
39   to someone else's commit that came earlier, what you need to do is:
40     1. $ git pull
41     2. Verify that your ChangeLog entry is still the top-most one.
42     3. If it is not, then edit ChangeLog to move it to the top, and
43        $ git commit --amend ChangeLog
44     4. $ gitk
45     5. $ git push
47 * When you commit a contributor's patch, please
48   - add a reasonable ChangeLog entry in the usual style (meaningful
49     summary line and detailed change list),
50   - if the contribution is so small that it does not require a
51     copyright assignment (cf.
52     https://www.gnu.org/prep/maintain/html_node/Legally-Significant.html )
53     add a line:
54     Copyright-paperwork-exempt: Yes
55   - use the 'git commit' option --author="Contributor Name <email@address>"
58 License Notices
59 ===============
61 In *.m4 files, use a notice like this:
62   dnl Copyright (C) YEARS Free Software Foundation, Inc.
63   dnl This file is free software; the Free Software Foundation
64   dnl gives unlimited permission to copy and/or distribute it,
65   dnl with or without modifications, as long as this notice is preserved.
67 In lib/, tests/, build-aux/ files, except those that are shared with glibc,
68 use the license notices from etc/license-notices/ . This avoids gratuitous
69 differences in wording, as well misunderstandings when a license notice
70 would say "This program ...".
73 Test Suite
74 ==========
76 When adding a module, add a unit test module as well.  This is our best
77 chance to catch portability problems.
79 A unit test can have many sub-tests. Try to make the sub-tests independent
80 of each other, so that it becomes easy to disable some sub-tests by enclosing
81 them in #if 0 ... #endif.
83 The main() function's exit code meaning is:
84   - 0: PASS
85   - 77: SKIP; you should print the reason why the test is skipped.
86   - 99: ERROR, i.e. test framework error
87   - any other exit code < 126: FAIL
89 In tests that #include "macros.h" and use the ASSERT macro:
90 The main() function should, before it returns 0 (for PASS) or 77 (for SKIP)
91 test the value of test_exit_status and return that instead. So:
92   - not
93         return 0;
94     but instead
95         return test_exit_status;
96   - not
97         return result; // where result can be 0 or 1
98     but instead
99         return (result ? result : test_exit_status);
100   - not
101         fputs ("Skipping test: <reason>\n", stderr);
102         return 77;
103     but instead
104         if (test_exit_status != EXIT_SUCCESS)
105           return test_exit_status;
106         fputs ("Skipping test: <reason>\n", stderr);
107         return 77;
108     Only at the beginning of the main() function, when ASSERT has not yet been
109     invoked, we know that test_exit_status must be zero and can therefore write
110         fputs ("Skipping test: <reason>\n", stderr);
111         return 77;
112     directly.
115 Maintaining high quality
116 ========================
118 It is a good idea to occasionally create a testdir of all of Gnulib:
119   $ rm -rf ../testdir-all; ./gnulib-tool --create-testdir --dir=../testdir-all --with-c++-tests --without-privileged-tests --single-configure `./all-modules`
120 and test this directory on various platforms:
121   - Linux/glibc systems,
122   - Linux/musl systems,
123   - macOS,
124   - FreeBSD,
125   - NetBSD,
126   - OpenBSD,
127   - AIX,
128   - Solaris 10 and 11,
129   - Cygwin,
130   - Haiku,
131   - Android,
132   - and other platforms of your choice.
134 There is a continuous integration that regularly performs this testing
135 on a Linux/glibc system: https://gitlab.com/gnulib/gnulib-ci
136 But this will catch only the most blatant mistakes.
139 Warning Options
140 ===============
142 For packages that use Gnulib, we recommend to use the 'warnings' or
143 'manywarnings' module, as documented in
144 https://www.gnu.org/software/gnulib/manual/html_node/warnings.html
145 https://www.gnu.org/software/gnulib/manual/html_node/manywarnings.html
147 When building Gnulib testdirs, e.g. when preparing a Gnulib patch,
148 there are three possible approaches:
150 * The simplest approach, which warns about the most common mistakes, is to
151   use GCC's -Wall option, both for C and C++ compilation units. Just set
152     $ ./configure CPPFLAGS="-Wall"
153     $ make
154   You should generally fix all compiler warnings that you see from this
155   approach.
157 * If you are developing on a glibc system and have GCC version 13 binaries
158   available, here's a recipe that will find more mistakes, but is nearly
159   as easy to use. Here, different warning options are needed for C and
160   for C++:
161     $ WARN_GCC13=`echo '
162       -fanalyzer
163       -Wall
164       -Warith-conversion
165       -Wcast-align=strict
166       -Wdate-time
167       -Wdisabled-optimization
168       -Wduplicated-cond
169       -Wextra
170       -Wformat-signedness
171       -Winit-self
172       -Winvalid-pch
173       -Wlogical-op
174       -Wmissing-include-dirs
175       -Wopenmp-simd
176       -Woverlength-strings
177       -Wpacked
178       -Wpointer-arith
179       -Wstrict-overflow
180       -Wsuggest-final-methods
181       -Wsuggest-final-types
182       -Wsync-nand
183       -Wsystem-headers
184       -Wtrampolines
185       -Wuninitialized
186       -Wunknown-pragmas
187       -Wunsafe-loop-optimizations
188       -Wvariadic-macros
189       -Wvector-operation-performance
190       -Wwrite-strings
191       -Warray-bounds=2
192       -Wattribute-alias=2
193       -Wformat-overflow=2
194       -Wformat-truncation=2
195       -Wshift-overflow=2
196       -Wunused-const-variable=2
197       -Wvla-larger-than=4031
198       -Wno-empty-body
199       -Wno-analyzer-allocation-size
200       -Wno-analyzer-fd-double-close
201       -Wno-analyzer-double-fclose
202       -Wno-analyzer-double-free
203       -Wno-analyzer-fd-leak
204       -Wno-analyzer-fd-use-after-close
205       -Wno-analyzer-fd-use-without-check
206       -Wno-analyzer-free-of-non-heap
207       -Wno-analyzer-malloc-leak
208       -Wno-analyzer-mismatching-deallocation
209       -Wno-analyzer-null-argument
210       -Wno-analyzer-null-dereference
211       -Wno-analyzer-out-of-bounds
212       -Wno-analyzer-possible-null-argument
213       -Wno-analyzer-possible-null-dereference
214       -Wno-analyzer-use-after-free
215       -Wno-analyzer-use-of-pointer-in-stale-stack-frame
216       -Wno-analyzer-use-of-uninitialized-value
217       -Wno-analyzer-va-arg-type-mismatch
218       -Wno-attribute-warning
219       -Wno-cast-align
220       -Wno-clobbered
221       -Wno-dangling-pointer
222       -Wno-format
223       -Wno-implicit-fallthrough
224       -Wno-maybe-uninitialized
225       -Wno-missing-field-initializers
226       -Wno-restrict
227       -Wno-sign-compare
228       -Wno-switch
229       -Wno-type-limits
230       -Wno-unused-parameter
231     ' | tr -d '\n' | sed -e 's/  */ /g'`
232     $ WARN_CFLAGS_GCC13="$WARN_GCC13 -Wnested-externs -Wshadow=local -Wno-discarded-qualifiers"
233     $ WARN_CXXFLAGS_GCC13="$WARN_GCC13 -Wno-cpp"
234     $ ./configure CFLAGS="-O2 -g $WARN_CFLAGS_GCC13" CXXFLAGS="-O2 -g $WARN_CXXFLAGS_GCC13"
235     $ make
236   You should generally fix all compiler warnings that you see from this
237   approach, or report when this approach produced a pointless warning
238   (so that we can fix the value of WARN_GCC13 above).
240 * If you are developing on a glibc system and have GCC version 13 binaries
241   available: Here's a recipe that will find even more mistakes, but it
242   requires that you are willing to filter out and ignore pointless warnings.
243     $ WARN_GCC13=`echo '
244       -fanalyzer
245       -Wall
246       -Warith-conversion
247       -Wcast-align=strict
248       -Wdate-time
249       -Wdisabled-optimization
250       -Wduplicated-cond
251       -Wextra
252       -Wformat-signedness
253       -Winit-self
254       -Winvalid-pch
255       -Wlogical-op
256       -Wmissing-include-dirs
257       -Wnull-dereference
258       -Wopenmp-simd
259       -Woverlength-strings
260       -Wpacked
261       -Wpointer-arith
262       -Wstrict-overflow
263       -Wsuggest-attribute=format
264       -Wsuggest-final-methods
265       -Wsuggest-final-types
266       -Wsync-nand
267       -Wsystem-headers
268       -Wtrampolines
269       -Wuninitialized
270       -Wunknown-pragmas
271       -Wunsafe-loop-optimizations
272       -Wvariadic-macros
273       -Wvector-operation-performance
274       -Wwrite-strings
275       -Warray-bounds=2
276       -Wattribute-alias=2
277       -Wformat-overflow=2
278       -Wformat=2
279       -Wformat-truncation=2
280       -Wimplicit-fallthrough=5
281       -Wshift-overflow=2
282       -Wunused-const-variable=2
283       -Wvla-larger-than=4031
284       -Wno-empty-body
285       -Wno-analyzer-double-fclose
286       -Wno-analyzer-double-free
287       -Wno-analyzer-free-of-non-heap
288       -Wno-analyzer-malloc-leak
289       -Wno-analyzer-null-argument
290       -Wno-analyzer-null-dereference
291       -Wno-analyzer-use-after-free
292       -Wno-attribute-warning
293       -Wno-cast-align
294       -Wno-clobbered
295       -Wno-format-nonliteral
296       -Wno-sign-compare
297       -Wno-type-limits
298       -Wno-unused-parameter
299     ' | tr -d '\n' | sed -e 's/  */ /g'`
300     $ WARN_CFLAGS_GCC13="$WARN_GCC13 -Wnested-externs -Wshadow=local"
301     $ WARN_CXXFLAGS_GCC13="$WARN_GCC13 -Wno-cpp"
302     $ ./configure CFLAGS="-O2 -g $WARN_CFLAGS_GCC13" CXXFLAGS="-O2 -g $WARN_CXXFLAGS_GCC13"
303     $ make
304   With this approach, use your own judgement whether to fix warnings
305   arising from your new code or not.
306   Do *not* submit patches to silence warnings from existing code:
307     - For these warnings, often the cure will be worse than the disease.
308     - Some of the warnings are false positives. Rather than silencing
309       these warnings, we prefer to report them in the GCC bug tracker
310       and wait until they are fixed in a future GCC release.
312 Similarly, for clang version 16 you can use the following recipe, that uses
313 selected warning options from
314 https://releases.llvm.org/16.0.0/tools/clang/docs/DiagnosticsReference.html :
315   $ WARN_CLANG16=`echo '
316     -Wall
317     -Wanon-enum-enum-conversion
318     -Warc-repeated-use-of-weak
319     -Warray-bounds-pointer-arithmetic
320     -Warray-parameter
321     -Watomic-properties
322     -Wbinary-literal
323     -Wbit-int-extension
324     -Wbitfield-enum-conversion
325     -Wbitwise-op-parentheses
326     -Wbool-operation
327     -Wc++-compat
328     -Wc2x-compat
329     -Wc2x-extensions
330     -Wc99-compat
331     -Wc99-designator
332     -Wc99-extensions
333     -Wcalled-once-parameter
334     -Wcast-function-type
335     -Wchar-subscripts
336     -Wcomment
337     -Wcompletion-handler
338     -Wcomplex-component-init
339     -Wcompound-token-split
340     -Wconsumed
341     -Wconversion
342     -Wcstring-format-directive
343     -Wcuda-compat
344     -Wdate-time
345     -Wdelimited-escape-sequence-extension
346     -Wdeprecated
347     -Wdeprecated-dynamic-exception-spec
348     -Wdeprecated-implementations
349     -Wdeprecated-this-capture
350     -Wdeprecated-writable-strings
351     -Wdirect-ivar-access
352     -Wdocumentation
353     -Wdocumentation-deprecated-sync
354     -Wdocumentation-html
355     -Wdocumentation-pedantic
356     -Wdocumentation-unknown-command
357     -Wdollar-in-identifier-extension
358     -Wduplicate-decl-specifier
359     -Wduplicate-enum
360     -Wduplicate-method-arg
361     -Wduplicate-method-match
362     -Wdynamic-exception-spec
363     -Wembedded-directive
364     -Wempty-init-stmt
365     -Wempty-translation-unit
366     -Wenum-compare-conditional
367     -Wenum-conversion
368     -Wenum-enum-conversion
369     -Wenum-float-conversion
370     -Wexit-time-destructors
371     -Wexpansion-to-defined
372     -Wexplicit-ownership-type
373     -Wextra
374     -Wextra-semi
375     -Wfixed-enum-extension
376     -Wflexible-array-extensions
377     -Wfloat-overflow-conversion
378     -Wfloat-zero-conversion
379     -Wfor-loop-analysis
380     -Wformat
381     -Wformat-pedantic
382     -Wformat-type-confusion
383     -Wformat=2
384     -Wfour-char-constants
385     -Wframe-address
386     -Wfuse-ld-path
387     -Wfuture-attribute-extensions
388     -Wgcc-compat
389     -Wgnu
390     -Wgnu-anonymous-struct
391     -Wgnu-auto-type
392     -Wgnu-case-range
393     -Wgnu-complex-integer
394     -Wgnu-compound-literal-initializer
395     -Wgnu-conditional-omitted-operand
396     -Wgnu-designator
397     -Wgnu-empty-initializer
398     -Wgnu-empty-struct
399     -Wgnu-flexible-array-initializer
400     -Wgnu-flexible-array-union-member
401     -Wgnu-folding-constant
402     -Wgnu-imaginary-constant
403     -Wgnu-label-as-value
404     -Wgnu-line-marker
405     -Wgnu-null-pointer-arithmetic
406     -Wgnu-offsetof-extensions
407     -Wgnu-pointer-arith
408     -Wgnu-redeclared-enum
409     -Wgnu-statement-expression
410     -Wgnu-statement-expression-from-macro-expansion
411     -Wgnu-union-cast
412     -Wgnu-zero-line-directive
413     -Wgnu-zero-variadic-macro-arguments
414     -Wheader-hygiene
415     -Widiomatic-parentheses
416     -Wignored-qualifiers
417     -Wimplicit
418     -Wimplicit-fallthrough
419     -Wimplicit-fallthrough-per-function
420     -Wimplicit-function-declaration
421     -Wimplicit-int
422     -Wimplicit-retain-self
423     -Wimport-preprocessor-directive-pedantic
424     -Wincomplete-module
425     -Winconsistent-missing-destructor-override
426     -Winfinite-recursion
427     -Wint-in-bool-context
428     -Winvalid-or-nonexistent-directory
429     -Winvalid-utf8
430     -Wkeyword-macro
431     -Wlanguage-extension-token
432     -Wlocal-type-template-args
433     -Wlogical-op-parentheses
434     -Wlong-long
435     -Wloop-analysis
436     -Wmain
437     -Wmax-tokens
438     -Wmethod-signatures
439     -Wmicrosoft
440     -Wmicrosoft-anon-tag
441     -Wmicrosoft-charize
442     -Wmicrosoft-comment-paste
443     -Wmicrosoft-cpp-macro
444     -Wmicrosoft-end-of-file
445     -Wmicrosoft-enum-value
446     -Wmicrosoft-exception-spec
447     -Wmicrosoft-fixed-enum
448     -Wmicrosoft-flexible-array
449     -Wmicrosoft-redeclare-static
450     -Wmisleading-indentation
451     -Wmismatched-tags
452     -Wmissing-braces
453     -Wmissing-method-return-type
454     -Wmost
455     -Wmove
456     -Wnested-anon-types
457     -Wnewline-eof
458     -Wnon-gcc
459     -Wnon-modular-include-in-framework-module
460     -Wnon-modular-include-in-module
461     -Wnon-virtual-dtor
462     -Wnonportable-system-include-path
463     -Wnull-pointer-arithmetic
464     -Wnull-pointer-subtraction
465     -Wnullability-extension
466     -Wnullable-to-nonnull-conversion
467     -Wopenmp
468     -Wover-aligned
469     -Woverlength-strings
470     -Woverloaded-virtual
471     -Woverriding-method-mismatch
472     -Wpacked
473     -Wpacked-non-pod
474     -Wparentheses
475     -Wpedantic
476     -Wpedantic-core-features
477     -Wpessimizing-move
478     -Wpointer-arith
479     -Wpoison-system-directories
480     -Wpragma-pack
481     -Wpragma-pack-suspicious-include
482     -Wpragmas
483     -Wpre-c2x-compat
484     -Wpre-openmp-51-compat
485     -Wprofile-instr-missing
486     -Wquoted-include-in-framework-header
487     -Wrange-loop-analysis
488     -Wrange-loop-bind-reference
489     -Wrange-loop-construct
490     -Wreceiver-forward-class
491     -Wredundant-move
492     -Wredundant-parens
493     -Wreorder
494     -Wreorder-ctor
495     -Wreserved-user-defined-literal
496     -Wretained-language-linkage
497     -Wselector
498     -Wselector-type-mismatch
499     -Wself-assign
500     -Wself-assign-overloaded
501     -Wself-move
502     -Wsemicolon-before-method-body
503     -Wshadow-all
504     -Wshadow-field
505     -Wshadow-field-in-constructor
506     -Wshadow-field-in-constructor-modified
507     -Wshadow-uncaptured-local
508     -Wshift-sign-overflow
509     -Wsigned-enum-bitfield
510     -Wsometimes-uninitialized
511     -Wsource-uses-openmp
512     -Wspir-compat
513     -Wstatic-in-inline
514     -Wstrict-potentially-direct-selector
515     -Wstrict-selector-match
516     -Wstring-concatenation
517     -Wstring-conversion
518     -Wsuggest-destructor-override
519     -Wsuggest-override
520     -Wsuper-class-method-mismatch
521     -Wtautological-bitwise-compare
522     -Wtautological-compare
523     -Wtautological-constant-in-range-compare
524     -Wtautological-overlap-compare
525     -Wtautological-type-limit-compare
526     -Wtautological-unsigned-char-zero-compare
527     -Wtautological-unsigned-enum-zero-compare
528     -Wtautological-unsigned-zero-compare
529     -Wtautological-value-range-compare
530     -Wthread-safety
531     -Wthread-safety-analysis
532     -Wthread-safety-attributes
533     -Wthread-safety-beta
534     -Wthread-safety-negative
535     -Wthread-safety-precise
536     -Wthread-safety-reference
537     -Wthread-safety-verbose
538     -Wtype-limits
539     -Wunaligned-access
540     -Wundeclared-selector
541     -Wundef-prefix
542     -Wundefined-func-template
543     -Wundefined-internal-type
544     -Wundefined-reinterpret-cast
545     -Wunguarded-availability
546     -Wuninitialized
547     -Wuninitialized-const-reference
548     -Wunknown-pragmas
549     -Wunnamed-type-template-args
550     -Wunneeded-internal-declaration
551     -Wunneeded-member-function
552     -Wunreachable-code-fallthrough
553     -Wunreachable-code-loop-increment
554     -Wunsupported-dll-base-class-template
555     -Wunused
556     -Wunused-but-set-parameter
557     -Wunused-but-set-variable
558     -Wunused-const-variable
559     -Wunused-exception-parameter
560     -Wunused-function
561     -Wunused-label
562     -Wunused-lambda-capture
563     -Wunused-local-typedef
564     -Wunused-member-function
565     -Wunused-private-field
566     -Wunused-property-ivar
567     -Wunused-template
568     -Wunused-variable
569     -Wvariadic-macros
570     -Wvector-conversion
571     -Wweak-template-vtables
572     -Wweak-vtables
573     -Wzero-length-array
574     -Wno-bitwise-instead-of-logical
575     -Wno-c11-extensions
576     -Wno-cast-function-type-strict
577     -Wno-float-conversion
578     -Wno-format-nonliteral
579     -Wno-gnu-include-next
580     -Wno-implicit-float-conversion
581     -Wno-implicit-int-conversion
582     -Wno-implicit-int-float-conversion
583     -Wno-include-next-absolute-path
584     -Wno-missing-field-initializers
585     -Wno-reserved-macro-identifier
586     -Wno-shadow
587     -Wno-shorten-64-to-32
588     -Wno-sign-compare
589     -Wno-sign-conversion
590     -Wno-strict-prototypes
591     -Wno-switch
592     -Wno-unused-parameter
593     -Wno-tautological-constant-out-of-range-compare
594     -Wno-tautological-type-limit-compare
595     -Wno-tautological-unsigned-zero-compare
596     -Wno-tautological-value-range-compare
597     -Wno-unused-command-line-argument
598     -Wno-user-defined-warnings
599   ' | tr -d '\n' | sed -e 's/  */ /g'`
600   $ ./configure CFLAGS="-O2 -g $WARN_CLANG16" CXXFLAGS="-O2 -g $WARN_CLANG16"
601   $ make
602 Again, use your own judgement to determine whether to fix or ignore a
603 specific warning.
606 Information for gnulib-tool maintenance
607 ***************************************
609 Running the unit tests
610 ======================
612 The unit tests of gnulib-tool reside in the maint-tools repository, that is a
613 satellite repository of the main gnulib repository. Instructions how to obtain
614 it are in https://savannah.gnu.org/git/?group=gnulib .
616 To run the unit tests of gnulib-tool.sh:
617   $ cd maint-tools/gnulib-tool-tests/
618   $ GNULIB_TOOL_IMPL=sh ./test-all.sh
620 To run the unit tests of gnulib-tool.py:
621   $ cd maint-tools/gnulib-tool-tests/
622   $ GNULIB_TOOL_IMPL=py ./test-all.sh
624 It is *mandatory* that you run the test suite before pushing any change to
625 gnulib-tool.sh or gnulib-tool.py! If you fail to do so, and your change contains
626 a bug, it will start to affect users immediately.
629 Debugging the Python implementation of gnulib-tool
630 ==================================================
632 With Eclipse and PyDev as IDE
633 -----------------------------
635 * Download and configuration:
636   - Eclipse IDE from https://www.eclipse.org/downloads/packages/
637     (either the build for Java or for C/C++ should work fine;
638     either use the Eclipse Installer program at the top of the page,
639     or one of the individual download links below).
640   - PyDev from https://www.pydev.org/download.html
641     section "Install as Plugin".
642     (Don't use LiClipse, since the license costs money.)
643   - Follow https://www.pydev.org/manual_101_install.html,
644     replacing http://www.pydev.org/updates
645     with      https://www.pydev.org/updates
646   - Once installed, restart the IDE.
647   - Window > Preferences > PyDev > Interpreters > Python Interpreter:
648     New > path: /usr/bin/python3
649   - Window > Preferences > PyDev > Editor > Code Analysis:
650     Others > Redefinition of builtin symbols: Ignore
652 * Create a project:
653   Let GNULIB_DIR be my gnulib checkout.
654   - File > New > Project... > PyDev > PyDev Project. Call it 'gnulib-tool'.
655     Note that this is a project inside the Eclipse workspace, so far
656     unrelated to the GNULIB_DIR.
657   - Popup menu > New > Link to Existing Source
658     Name: gnulib
659     Path: <GNULIB_DIR>
661 * Create a run configuration:
662   - Run > Run Configurations... > Python Run
663     Popup menu > New configuration
664       Name: gnulib-tool.py
665       Main > Project: gnulib-tool
666       Main > Main Module: ${workspace_loc:gnulib-tool/gnulib/.gnulib-tool.py}
667       Arguments > Program arguments: --help
668   - Test it: Run this configuration.
670 * Create a debug configuration:
671   - Run > Debug Configurations... > gnulib-tool.py
672     Popup menu > Duplicate
673   - In the duplicate, set
674     Arguments > Working directory: /tmp/oath-toolkit/lib
675     Arguments > Program arguments: --add-import
677 * Debug it:
678   - Open GLImport.py.
679   - On the left-hand border of this editor, do "Add breakpoint".
680   - Run > Debug Configurations... > pick the duplicate. Press Debug.
683 Maintaining high quality
684 ========================
686 There is a continuous integration of gnulib-tool.py that runs the unit tests,
687 at https://gitlab.com/gnulib/gnulib-tool-ci/ .