summaryrefslogtreecommitdiff
path: root/HACKING
blob: 6e7a3e50edd85ef03c800bfb5fd6b4d52c06cca6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
Naming conventions:

include files:
- _lib: library without need for a process
- _service: library that needs a service process
- _plugin: plugin definition
- _protocol: structs used in network protocol
- exceptions:
  * gnunet_config.h      --- generated
  * platform.h           --- first included
  * plibc.h              --- external library
  * gnunet_common.h      --- fundamental routines
  * gnunet_directories.h --- generated
  * gettext.h            --- external library


binaries:
- gnunet-service-xxx: service process (has listen socket)
- gnunet-daemon-xxx: daemon process (no listen socket)
- gnunet-helper-xxx[-yyy]: SUID helper for module xxx
- gnunet-yyy: command-line tool for end-users
- libgnunet_plugin_xxx_yyy.so: plugin for API xxx
- libgnunetxxx.so: library for API xxx


logging:
- services and daemons use their directory name in GNUNET_log_setup (i.e. 'core')
  and log using plain 'GNUNET_log'.
- command-line tools use their full name in GNUNET_log_setup (i.e. 'gnunet-publish')
  and log using plain 'GNUNET_log'.
- service access libraries log using 'GNUNET_log_from' and use 
  'DIRNAME-api' for the component (i.e. 'core-api')
- pure libraries (without associated service) use 'GNUNET_log_from' with
  the component set to their library name (without lib
  or '.so'), which should also be their directory name (i.e. 'nat')
- plugins should use 'GNUNET_log_from' with the directory name
  and the plugin name combined to produce the component name (i.e. 'transport-tcp').
- logging should be unified per-file by defining a LOG macro with the
  appropriate arguments, along these lines:
  #define LOG(kind,...) GNUNET_log_from (kind, "example-api",__VA_ARGS__)


configuration:
- paths (that are substituted in all filenames) are in PATHS (have as few as possible)
- globals for the daemon are in [gnunetd] (for now, have as few as possible!)
- all options for a particular module (src/MODULE) are under [MODULE]
- options for a plugin of a module are under [MODULE-PLUGINNAME]
- options only for debugging / testing / profiling are under [TESTING],
  together with the options for the testing module itself


exported symbols:
- must start with "GNUNET_modulename_" and be defined in "modulename.c"
- exceptions: those defined in gnunet_common.h


private (library-internal) symbols (including structs & macros):
- must NOT start with any prefix
- must not be exported in a way that linkers could use them or
  other libraries might see them via headers; they must be either
  declared/defined in C source files or in headers that are in 
  the respective directory under src/modulename/ and NEVER be
  declared in src/include/.

testcases:
- must be called "test_module-under-test_case-description.c"
- "case-description" maybe omitted if there is only one test


performance tests:
- must be called "perf_module-under-test_case-description.c"
- "case-description" maybe omitted if there is only one performance test
- Must only be run if HAVE_BENCHMARKS is satisfied


src/ directories:
- gnunet-NAME: end-user applications (i.e., gnunet-search, gnunet-arm)
- gnunet-service-NAME: service processes with accessor library (i.e., gnunet-service-arm)
- libgnunetNAME: accessor library (_service.h-header) or standalone library (_lib.h-header)
- gnunet-daemon-NAME: daemon process without accessor library (i.e., gnunet-daemon-hostlist) and no GNUnet management port
- libgnunet_plugin_DIR_NAME: loadable plugins (i.e., libgnunet_plugin_transport_tcp)


Coding style:
- GNU guidelines generally apply
- declare only one variable per line, so 

  int i;
  int j;

  instead of

  int i,j;
- Indentation should be done using the 'pre-commit' script in the top-level
  directory using the patched (!) GNU indent.  See also the posting at
  https://gnunet.org/gnunetindentation


Build-system:

If you have code that is likely not to compile or build rules you might want to not
trigger for most developers, use "if HAVE_EXPERIMENTAL" in your Makefile.am.  Then
it is OK to (temporarily) add non-compiling (or known-to-not-port) code.

If you want to compile all testcases but NOT run them, run configure with the
--enable-test-suppression option.

If you want to run all testcases, including those that take a while, run configure with the
--enable-expensive-testcases option.

If you want to compile and run benchmarks, run configure with the
--enable-benchmarks option.

If you want to obtain code coverage results, run configure with the
--enable-coverage option and run the coverage.sh script in contrib/.


Minimum file-sharing system (in order of dependency):
gnunet-service-arm
gnunet-service-transport
gnunet-service-core
gnunet-daemon-hostlist
gnunet-daemon-topology
gnunet-service-statistics
gnunet-service-datastore
gnunet-service-datacache
gnunet-service-dht
gnunet-service-fs