Mercurial > irccd
comparison STYLE.md @ 773:8c44bbcbbab9
Misc: style, cleanup and update
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 26 Oct 2018 13:01:00 +0200 |
parents | b452f5ce799c |
children | 201ddc487807 |
comparison
equal
deleted
inserted
replaced
772:f5ccf65ae929 | 773:8c44bbcbbab9 |
---|---|
1 irccd CODING STYLE | 1 IRC Client Daemon CODING STYLE |
2 ================== | 2 ============================== |
3 | |
4 File content | |
5 ============ | |
6 | |
7 - Use UTF-8 charset, | |
8 - Use Unix line endings, | |
9 - Never write two blank consecutives blank lines. | |
10 | |
11 Indent | |
12 ====== | |
13 | |
14 Use tabs to indent and spaces for alignment. Tabs are meant and designed for | |
15 indenting code and have the advantage of being configurable. On the other hand | |
16 to keep code clean, you must align content with spaces only *within* a line. | |
17 | |
18 Note: we recommend 8 columns to avoid high number of indentations. | |
19 | |
20 Example (show whitespace in your editor) | |
21 | |
22 ```cpp | |
23 class foo { | |
24 public: | |
25 enum type { | |
26 dummy_value, // dummy comment | |
27 other_value // other comment | |
28 }; | |
29 | |
30 void long_function_name(very_long_type x1, | |
31 very_long_type x2) | |
32 { | |
33 const map<string, string> m{ | |
34 { "hostname", "127.0.0.1" }, | |
35 { "port", "6667" } | |
36 }; | |
37 } | |
38 }; | |
39 ``` | |
40 | |
41 As a rule of thumb, tabs must always be all length. | |
42 | |
43 Example of incorrect usage: | |
44 | |
45 ```cpp | |
46 { "hostname", "127.0.0.1" }, | |
47 { "port", "6667" } | |
48 ``` | |
49 | |
50 This example will not align correctly if tabstops are not set to 8. | |
3 | 51 |
4 C++ | 52 C++ |
5 === | 53 === |
6 | 54 |
7 Style | 55 Style |
8 ----- | 56 ----- |
9 | 57 |
10 - Always use 4 spaces as indentation, | 58 - Do not exceed 120 columns for lines of code, |
11 - Use UTF-8 charset, | 59 - Do not exceed 80 columns for comments, |
12 - Use Unix line endings, | |
13 - Do not exceed 120 characters for lines of code, | |
14 - Do not exceed 80 characters for comments, | |
15 - Never write two blank consecutives blank lines, | |
16 - Do not use bad words. | |
17 | 60 |
18 ### Braces | 61 ### Braces |
19 | 62 |
20 Braces follow the K&R style, they are never placed on their own lines except for | 63 Braces follow the K&R style, they are never placed on their own lines except for |
21 function definitions. | 64 function definitions. |
22 | 65 |
23 Do not put braces for single line statements except for clarity. | 66 Do not put braces for single line statements. |
24 | 67 |
25 if (condition) { | 68 ```cpp |
26 apply(); | 69 if (condition) { |
27 add(); | 70 apply(); |
28 } else | 71 add(); |
29 ok(); | 72 } else |
30 | 73 ok(); |
31 if (condition) | 74 |
32 validate(); | 75 if (condition) |
33 | 76 validate(); |
34 if (foo) { | 77 |
35 state = long + conditional + that + requires + several + lines + | 78 if (foo) |
36 to + complete; | 79 state = long + conditional + that + requires + several + lines + |
37 } | 80 to + complete; |
81 ``` | |
38 | 82 |
39 Functions require braces on their own lines. | 83 Functions require braces on their own lines. |
40 | 84 |
41 void function() | 85 ```cpp |
42 { | 86 void function() |
43 } | 87 { |
88 } | |
89 ``` | |
44 | 90 |
45 And a lambda has its braces on the same lines too: | 91 And a lambda has its braces on the same lines too: |
46 | 92 |
47 sort([&] (auto&) { | 93 ```cpp |
48 return true; | 94 sort([&] (auto&) { |
49 }); | 95 return true; |
96 }); | |
97 ``` | |
50 | 98 |
51 ### Spaces | 99 ### Spaces |
52 | 100 |
53 Each reserved keyword (e.g. `if`, `for`, `while`) requires a single space before | 101 Each reserved keyword (e.g. `if`, `for`, `while`) requires a single space before |
54 its argument. | 102 its argument. |
55 | 103 |
56 Normal function calls do not require it. | 104 Normal function calls do not require it. |
57 | 105 |
58 if (foo) | 106 ```cpp |
59 destroy(sizeof (int)); | 107 if (foo) |
108 destroy(sizeof (int)); | |
109 ``` | |
60 | 110 |
61 ### References and pointers | 111 ### References and pointers |
62 | 112 |
63 References and pointers are always next to the type name and not the variable. | 113 References and pointers are always next to the type name and not the variable. |
64 | 114 |
65 T& get(const std::string& name); | 115 ```cpp |
66 | 116 auto get(const std::string& name) -> T&; |
67 int* p = &x; | 117 |
118 int* p = &x; | |
119 ``` | |
120 | |
121 ### Trailing return syntax | |
122 | |
123 We use trailing return syntax everywhere, it has the following benefits: | |
124 | |
125 - Inner types don't need to be prefixed by class name, | |
126 - Functions are kept aligned correctly, focusing on the function name. | |
127 | |
128 ```cpp | |
129 auto func() -> std::string; | |
130 ``` | |
68 | 131 |
69 ### Naming | 132 ### Naming |
70 | 133 |
71 - English names, | 134 - English names, |
72 - Member variables have trailing underscore (e.g foo\_bar\_), | 135 - Member variables have trailing underscore (e.g foo\_bar\_), |
73 - No hungarian notation. | 136 - No hungarian notation. |
74 | 137 |
75 Everything is in `underscore_case` except template parameters and macros. | 138 Everything is in `underscore_case` except template parameters and macros. |
76 | 139 |
77 #if defined(FOO) | 140 ```cpp |
78 # include <foo.hpp> | 141 #if defined(FOO) |
79 #endif | 142 # include <foo.hpp> |
80 | 143 #endif |
81 namespace baz { | 144 |
82 | 145 namespace baz { |
83 class object { | 146 |
84 private: | 147 class object { |
85 std::string name_; | 148 private: |
86 | 149 std::string name_; |
87 public: | 150 |
88 inline const std::string& name() const noexcept | 151 public: |
89 { | 152 auto name() const noexcept -> const std::string&; |
90 return name_; | 153 }; |
91 } | 154 |
92 }; | 155 template <typename Archive> |
93 | 156 void open(const Archive& ar) |
94 template <typename Archive> | 157 { |
95 void open(const Archive& ar) | 158 bool is_valid = false; |
96 { | 159 } |
97 bool is_valid = false; | 160 |
98 } | 161 } // !baz |
99 | 162 ``` |
100 } // !baz | |
101 | 163 |
102 ### Header guards | 164 ### Header guards |
103 | 165 |
104 Do not use `#pragma once`. | 166 Do not use `#pragma once`. |
105 | 167 |
106 Header guards are usually named **PROJECT_COMPONENT_FILENAME_HPP**. | 168 Header guards are usually named `PROJECT_COMPONENT_FILENAME_HPP`. |
107 | 169 |
108 #ifndef FOO_COMMON_UTIL_HPP | 170 ```cpp |
109 #define FOO_COMMON_UTIL_HPP | 171 #ifndef FOO_COMMON_UTIL_HPP |
110 | 172 #define FOO_COMMON_UTIL_HPP |
111 #endif // !FOO_COMMON_UTIL_HPP | 173 |
174 #endif // !FOO_COMMON_UTIL_HPP | |
175 ``` | |
112 | 176 |
113 ### Enums | 177 ### Enums |
114 | 178 |
115 Enumerations constants are always defined in separate line to allow commenting | 179 Enumerations constants are always defined in separate line to allow commenting |
116 them as doxygen. | 180 them as doxygen. |
117 | 181 |
118 Enum class are encouraged. | 182 Enum class are encouraged. |
119 | 183 |
120 enum class color { | 184 ```cpp |
121 blue, | 185 enum class color { |
122 red, | 186 blue, |
123 green | 187 red, |
124 }; | 188 green |
189 }; | |
190 ``` | |
125 | 191 |
126 ### Switch | 192 ### Switch |
127 | 193 |
128 In a switch case statement, you **must** not declare variables and not indent | 194 In a switch case statement, you **must** not declare variables and not indent |
129 cases. | 195 cases. |
130 | 196 |
131 switch (variable) { | 197 ```cpp |
132 case foo: | 198 switch (variable) { |
133 do_some_stuff(); | 199 case foo: |
134 break; | 200 do_some_stuff(); |
135 default: | 201 break; |
136 break; | 202 default: |
137 } | 203 break; |
204 } | |
205 ``` | |
138 | 206 |
139 ### Files | 207 ### Files |
140 | 208 |
141 - Use `.cpp` and `.hpp` as file extensions, | 209 - Use `.cpp` and `.hpp` as file extensions, |
142 - Filenames are all lowercase. | 210 - Filenames are all lowercase. |
143 | 211 |
144 ### Comments | 212 ### Comments |
145 | 213 |
146 Avoid useless comments in source files. Comment complex things or why it is done | 214 Avoid useless comments in source files. Comment complex things or why it is done |
147 like this. However any public function in the .hpp **must** be documented as | 215 like this. However any public function in the .hpp **must** be documented as |
148 doxygen without exception. | 216 doxygen without exception. |
149 | 217 |
150 /* | 218 ```cpp |
151 * Multi line comments look like | 219 /* |
152 * this. | 220 * Multi line comments look like |
153 */ | 221 * this. |
154 | 222 */ |
155 // Short comment | 223 |
224 // Short comment | |
225 ``` | |
156 | 226 |
157 Use `#if 0` to comment blocks of code. | 227 Use `#if 0` to comment blocks of code. |
158 | 228 |
229 ```cpp | |
159 #if 0 | 230 #if 0 |
160 broken_stuff(); | 231 broken_stuff(); |
161 #endif | 232 #endif |
233 ``` | |
162 | 234 |
163 ### Includes | 235 ### Includes |
164 | 236 |
165 The includes should always come in the following order. | 237 The includes should always come in the following order. |
166 | 238 |
167 1. C++ headers | 239 1. C++ headers |
168 2. C header | 240 2. C header |
169 3. Third party libraries | 241 3. Third party libraries |
170 4. Application headers in "" | 242 4. Application headers in "" |
171 | 243 |
172 #include <cstring> | 244 ```cpp |
173 #include <cerrno> | 245 #include <cstring> |
174 | 246 #include <cerrno> |
175 #include <sys/stat.h> | 247 |
176 | 248 #include <sys/stat.h> |
177 #include <libircclient.h> | 249 |
178 | 250 #include <libircclient.h> |
179 #include "foo.h" | 251 |
180 | 252 #include "foo.h" |
181 **Note**: always use C++ headers for C equivalent, stdio.h -> cstdio, etc. | 253 ``` |
182 | 254 |
183 ### Commit messages | 255 Note: always use C++ headers for C equivalent, stdio.h -> cstdio, etc. |
184 | |
185 Commit messages are written using the following syntax: | |
186 | |
187 Topic: short message less than 80 characters | |
188 | |
189 Optional additional description if needed. | |
190 | |
191 Replace `Topic` with one of the following: | |
192 | |
193 - **CMake**: for the build system, | |
194 - **Docs**: for the documentation, | |
195 - **Misc**: for miscellaneous files, | |
196 - **Tests**: for the unit tests. | |
197 | 256 |
198 Programming | 257 Programming |
199 ----------- | 258 ----------- |
200 | 259 |
201 ### C language | 260 ### C language |
202 | 261 |
203 Do not use old C stuff like `void *`, `srand/rand`, `printf` or anything that | 262 Do not use old C stuff like `void*`, `srand/rand`, `printf` or anything that |
204 can be rewritten in modern C++. | 263 can be rewritten in modern C++. |
205 | 264 |
206 ### RTTI | 265 ### RTTI |
207 | 266 |
208 Usage of `dynamic_cast` and `typeid` are completely disallowed in any shape of | 267 Usage of `dynamic_cast` and `typeid` are completely disallowed in any shape of |
212 | 271 |
213 It is recommended to pass parameters by value or const reference. Usage of | 272 It is recommended to pass parameters by value or const reference. Usage of |
214 non-const reference as output parameter is **discouraged** and should be avoided | 273 non-const reference as output parameter is **discouraged** and should be avoided |
215 in many case because it does not allow chaining of expressions like: | 274 in many case because it does not allow chaining of expressions like: |
216 | 275 |
217 std::cout << reverse(upper(clean(" hello world! "))) << std::endl; | 276 ```cpp |
277 std::cout << reverse(upper(clean(" hello world! "))) << std::endl; | |
278 ``` | |
218 | 279 |
219 If your function is designed to return a modified value passed as argument, it | 280 If your function is designed to return a modified value passed as argument, it |
220 is better to take it by value and modify it directly. | 281 is better to take it by value and modify it directly. |
221 | 282 |
222 std::string clean(std::string input) | 283 ```cpp |
223 { | 284 auto clean(std::string input) -> std::string |
224 if (!input.empty() && input.back() == '\r') | 285 { |
225 input.pop_back(); | 286 if (!input.empty() && input.back() == '\r') |
226 | 287 input.pop_back(); |
227 return input; | 288 |
228 } | 289 return input; |
290 } | |
291 ``` | |
229 | 292 |
230 Never pass primitive types as const value. | 293 Never pass primitive types as const value. |
231 | 294 |
232 ### Assertions | 295 ### Assertions |
233 | 296 |
235 errors. | 298 errors. |
236 | 299 |
237 For example, you may use `assert` to verify that the developer access the data | 300 For example, you may use `assert` to verify that the developer access the data |
238 between the bounds of an array: | 301 between the bounds of an array: |
239 | 302 |
240 T& operator[](unsigned index) | 303 ```cpp |
241 { | 304 auto operator[](unsigned index) -> T& |
242 assert(index < length_); | 305 { |
243 | 306 assert(index < length_); |
244 return data_[index]; | 307 |
245 } | 308 return data_[index]; |
309 } | |
310 ``` | |
246 | 311 |
247 The `assert` macro is not meant to check that a function succeeded, this code | 312 The `assert` macro is not meant to check that a function succeeded, this code |
248 must not be written that way: | 313 must not be written that way: |
249 | 314 |
250 assert(listen(10)); | 315 ```cpp |
316 assert(listen(10)); | |
317 ``` | |
251 | 318 |
252 ### Exceptions | 319 ### Exceptions |
253 | 320 |
254 You must use exceptions to indicate an error that was unexpected such as: | 321 You must use exceptions to indicate an error that was unexpected such as: |
255 | 322 |
256 - Failing to open a file, | 323 - Failing to open a file, |
257 - I/O unexpected errors, | 324 - I/O unexpected errors, |
258 - Parsing errors, | 325 - Parsing errors, |
259 - User errors. | 326 - User errors. |
260 | 327 |
261 You may use the C++ standard exceptions defined in the stdexcept header but if | 328 You may use the C++ standard exceptions defined in the stdexcept header but if |
262 you need to carry more data within your exception, you should derive from | 329 you need to carry more data within your exception, you should derive from |
263 `std::exception`. | 330 `std::exception`. |
264 | 331 |
272 Basic utility functions should be defined in a namespace as a free function not | 339 Basic utility functions should be defined in a namespace as a free function not |
273 as a static member function, we're doing C++ not Java. | 340 as a static member function, we're doing C++ not Java. |
274 | 341 |
275 Example: | 342 Example: |
276 | 343 |
277 namespace util { | 344 ```cpp |
278 | 345 namespace util { |
279 std::string clean(std::string input); | 346 |
280 | 347 auto clean(std::string input) -> std::string; |
281 } // !util | 348 |
349 } // !util | |
350 ``` | |
282 | 351 |
283 ### Variables initialization | 352 ### Variables initialization |
284 | 353 |
285 Use parentheses to initialize non primitive types: | 354 Use parentheses to initialize non primitive types: |
286 | 355 |
287 throw std::runtime_error("foo"); | 356 ```cpp |
288 | 357 throw std::runtime_error("foo"); |
289 my_class obj("bar"); | 358 |
359 my_class obj("bar"); | |
360 ``` | |
290 | 361 |
291 Use brace initialization when you want to use an initializer list, type | 362 Use brace initialization when you want to use an initializer list, type |
292 elision: | 363 elision: |
293 | 364 |
294 std::vector<int> v{1, 2, 3}; | 365 ```cpp |
295 | 366 std::vector<int> v{1, 2, 3}; |
296 foo({1, 2}); // type deduced | 367 |
297 | 368 foo({1, 2}); // type deduced |
298 return { "true", false }; // std::pair returned | 369 |
370 return { "true", false }; // std::pair returned | |
371 ``` | |
299 | 372 |
300 Use the assignment for primitive types: | 373 Use the assignment for primitive types: |
301 | 374 |
302 int x = 123; | 375 ```cpp |
303 bool is_valid = true; | 376 int x = 123; |
377 bool is_valid = true; | |
378 ``` | |
304 | 379 |
305 ### Classes | 380 ### Classes |
306 | 381 |
307 Classes are usually defined in the following order: | 382 Classes are usually defined in the following order: |
308 | 383 |
309 1. Public inner types (enums, classes), | 384 1. Public inner types (enums, classes), |
310 2. Protected/private members | 385 2. Protected/private members and functions |
311 3. Public functions | 386 3. Public static functions. |
312 | 387 3. Public member functions |
313 class foo { | 388 4. Public virtual functions. |
314 public: | 389 |
315 enum class type { | 390 ```cpp |
316 a, | 391 class foo { |
317 b | 392 public: |
318 }; | 393 enum class type { |
319 | 394 a, |
320 private: | 395 b |
321 int member_{0}; | 396 }; |
322 | 397 |
323 public: | 398 private: |
324 void some_function(); | 399 int member_{0}; |
325 }; | 400 |
401 public: | |
402 void some_function(); | |
403 }; | |
404 ``` | |
326 | 405 |
327 ### Structs | 406 ### Structs |
328 | 407 |
329 Do not use C structs unless you have very good reason to do so. If you want to | 408 Use structs for objects that only need to store public data and have no |
330 pack some data, just use `class` and make all fields public. | 409 invariants. For example PODs and traits match this criteria: |
331 | 410 |
332 class point { | 411 ```cpp |
333 public: | 412 struct point { |
334 int x{0}; | 413 int x{0}; |
335 int y{0}; | 414 int y{0}; |
336 }; | 415 }; |
416 | |
417 template <> | |
418 struct info_traits<point> { | |
419 template <typename Archive> | |
420 static void serialize(Archive& ar, const point& point) | |
421 { | |
422 ar.write(point.x); | |
423 ar.write(point.y); | |
424 } | |
425 }; | |
426 ``` | |
337 | 427 |
338 ### Return | 428 ### Return |
339 | 429 |
340 The preferred style is to return early in case of errors. That makes the code | 430 The preferred style is to return early in case of errors. That makes the code |
341 more linear and not highly indented. | 431 more linear and not highly indented. |
342 | 432 |
343 This code is preferred: | 433 This code is preferred: |
344 | 434 |
345 if (a_condition_is_not_valid) | 435 ```cpp |
346 return nullptr; | 436 if (a_condition_is_not_valid) |
347 if (an_other_condition) | 437 return nullptr; |
348 return nullptr; | 438 if (an_other_condition) |
349 | 439 return nullptr; |
350 auto x = std::make_shared<object>(); | 440 |
351 | 441 auto x = std::make_shared<object>(); |
352 x->start(); | 442 |
353 x->save(); | 443 x->start(); |
354 | 444 x->save(); |
355 return x; | 445 |
446 return x; | |
447 ``` | |
356 | 448 |
357 Additional rules: | 449 Additional rules: |
358 | 450 |
359 - Do never put parentheses between the returned value, | 451 - Do never put parentheses between the returned value, |
360 - Do not put a else branch after a return. | 452 - Do not put a else branch after a return. |
361 | 453 |
362 ### Auto | 454 ### Auto |
363 | 455 |
364 We encorage usage of `auto`, it reduces code maintainance as you don't need to | 456 We encorage usage of `auto`, it reduces code maintainance as you don't need to |
365 change your code when your rename types. | 457 change your code when your rename types. |
366 | 458 |
367 ````cpp | 459 ```cpp |
368 auto it = std::find_if(v.begin(), v.end(), [&] (const auto& obj) { | 460 auto it = std::find_if(v.begin(), v.end(), [&] (const auto& obj) { |
369 return obj.key() == "foo"; | 461 return obj.key() == "foo"; |
370 }); | 462 }); |
371 | 463 |
372 for (const auto& pair : a_map) | 464 for (const auto& pair : a_map) |
373 std::cout << pair.first << " = " << pair.second << std::endl; | 465 std::cout << pair.first << " = " << pair.second << std::endl; |
374 ```` | 466 ``` |
375 | 467 |
376 But do not use `auto` to write code like in python, this is not acceptable: | 468 But do not use `auto` to write code like in python, this is not acceptable: |
377 | 469 |
378 ````cpp | 470 ```cpp |
379 auto o = my_object("foo"); | 471 auto o = my_object("foo"); |
380 ```` | 472 ``` |
473 | |
474 ### String views | |
475 | |
476 Use `std::string_view` each time you need a string that you will not own, this | |
477 includes: temporary arguments, return values, compile time constants. | |
478 | |
479 ```cpp | |
480 const std::string_view version("1.0"); | |
481 | |
482 void load(std::string_view id, std::string_view path) | |
483 { | |
484 std::cout << "loading: " << id << " from path: " << path << std::endl; | |
485 } | |
486 ``` | |
487 | |
488 ### Optional values | |
489 | |
490 Use `std::optional` to indicate a null value considered as valid. For example, | |
491 searching a value that may not exist. | |
492 | |
493 ```cpp | |
494 auto find(std::string_view id) -> std::optional<int> | |
495 { | |
496 if (auto it = foo.find(id); it != foo.end()) | |
497 return it->second; | |
498 | |
499 return std::nullopt; | |
500 } | |
501 ``` | |
502 | |
503 ### Avoid definitions in headers | |
504 | |
505 Try to avoid as much as possible function definition in header file. It slow | |
506 down compilation because the compiler has to parse the syntax over and over. | |
507 It's even worse as you may need to recompile a lot of files when you change a | |
508 header rather than a source file. | |
509 | |
510 CMake | |
511 ===== | |
512 | |
513 Style | |
514 ----- | |
515 | |
516 - Try to keep line shorter than 80 columns | |
517 | |
518 ### Spaces | |
519 | |
520 Each programming keyword (e.g. `if`, `foreach`, `while`) requires a single space | |
521 before its argument, otherwise write opening parenthese directly after. | |
522 | |
523 ```cmake | |
524 foreach (c ${COMPONENTS}) | |
525 string(TOUPPER ${c} CMP) | |
526 | |
527 if (${WITH_${CMP}}) | |
528 add_executable(${c} ${c}.cpp) | |
529 endif () | |
530 endforeach () | |
531 ``` | |
532 | |
533 ### Line breaks | |
534 | |
535 When CMake lines goes too long, you should indent arguments at the same level, | |
536 it's also common to see named argument values indented even more. | |
537 | |
538 ```cmake | |
539 set( | |
540 FILES | |
541 ${myapp_SOURCE_DIR}/main.cpp | |
542 ${myapp_SOURCE_DIR}/foo.cpp | |
543 ${myapp_SOURCE_DIR}/bar.cpp | |
544 ) | |
545 | |
546 command_with_lot_of_arguments( | |
547 TARGET foo | |
548 INSTALL On | |
549 SOURCES | |
550 ${myapp_SOURCE_DIR}/main.cpp | |
551 ${myapp_SOURCE_DIR}/foo.cpp | |
552 ${myapp_SOURCE_DIR}/bar.cpp | |
553 COMMENT "Some comment" | |
554 ``` | |
555 | |
556 Modern CMake | |
557 ------------ | |
558 | |
559 CMake evolves over time, if you have read very old articles there is a chance | |
560 that what you have read is actually deprecated and replaced by other features. | |
561 The following list is a short summary of modern CMake features that you must | |
562 use. | |
563 | |
564 ### Imported targets | |
565 | |
566 When they are available, use imported targets rather than plain variables. They | |
567 offer complete dependency tracking with options and include directories as well. | |
568 | |
569 ```cmake | |
570 find_package(Boost COMPONENTS system) | |
571 target_link_libraries(main Boost::system) | |
572 ``` | |
573 | |
574 ### Generator expressions | |
575 | |
576 Use generator expressions when it make sense. For example you should use them | |
577 for variables that are not used at generation time (e.g CMAKE\_BUILD\_TYPE). | |
578 | |
579 ```cmake | |
580 target_include_directories( | |
581 myapp | |
582 $<BUILD_INTERFACE:${myapp_SOURCE_DIR}> | |
583 $<INSTALL_INTERFACE:include> | |
584 ) | |
585 ``` | |
586 | |
587 Warning: do never test against `CMAKE_BUILD_TYPE` in any CMakeLists.txt, IDEs | |
588 like Visual Studio will mismatch what you'll put in the conditions. | |
589 | |
590 ### Avoid global scoping | |
591 | |
592 The following commands must be avoided as much as possible: | |
593 | |
594 - `link_directories`, | |
595 - `link_libraries`, | |
596 - `include_directories`, | |
597 - `add_definitions`. | |
598 | |
599 They pollute the global namespace, all targets defined after these commands will | |
600 be built against those settings. Instead, you should use the per-targets | |
601 commands. | |
602 | |
603 ```cmake | |
604 target_include_directories( | |
605 mylib | |
606 PUBLIC | |
607 $<BUILD_INTERFACE:${mylib_SOURCE_DIR}> | |
608 $<INSTALL_INTERFACE:include> | |
609 ) | |
610 target_link_libraries(mylib foo) | |
611 ``` | |
612 | |
613 ### Defining sources | |
614 | |
615 You MUST never use any kind of `file(GLOB)` commands to list sources for an | |
616 executable. CMake is designed to be re-called by itself only when required, | |
617 having such a construct will not let CMake be able to detect if you have | |
618 added/removed files in your source directory. Instead, you MUST always specify | |
619 all source by hands. | |
620 | |
621 ```cmake | |
622 set( | |
623 FILES | |
624 ${myapp_SOURCE_DIR}/main.cpp | |
625 ${myapp_SOURCE_DIR}/a.cpp | |
626 ${myapp_SOURCE_DIR}/b.cpp | |
627 ) | |
628 | |
629 add_executable(myapp ${FILES}) | |
630 ``` | |
631 | |
632 Markdown | |
633 ======== | |
634 | |
635 Headers | |
636 ------- | |
637 | |
638 For 1st and 2nd level headers, use `===` and `---` delimiters and underline the | |
639 whole title. Otherwise use `###`. | |
640 | |
641 ```markdown | |
642 Top level title | |
643 =============== | |
644 | |
645 Sub title | |
646 --------- | |
647 | |
648 ### Header 3 | |
649 | |
650 #### Header 4 | |
651 | |
652 ##### Header 5 | |
653 | |
654 ###### Header 6 | |
655 ``` | |
656 | |
657 Lists | |
658 ----- | |
659 | |
660 Use hyphens for unordered lists for consistency, do not indent top level lists, | |
661 then indent by two spaces each level | |
662 | |
663 ```markdown | |
664 - unordered list 1 | |
665 - unordered list 2 | |
666 - sub unordered item | |
667 | |
668 1. unordered list 1 | |
669 2. unordered list 2 | |
670 2.1. sub unordered item | |
671 ``` | |
672 | |
673 Code blocks | |
674 ----------- | |
675 | |
676 You can use three backticks and the language specifier or just indent a block by | |
677 for leading spaces if you don't need syntax. | |
678 | |
679 ```cpp | |
680 std::cout << "hello world" << std::endl; | |
681 ``` | |
682 | |
683 And without syntax: | |
684 | |
685 ```markdown | |
686 This is simple code block. | |
687 ``` | |
688 | |
689 Tables | |
690 ------ | |
691 | |
692 Tables are supported and formatted as following: | |
693 | |
694 ```markdown | |
695 | header 1 | header 2 | | |
696 |----------|----------| | |
697 | item 1 | item 2 | | |
698 ``` | |
699 | |
700 Alerts | |
701 ------ | |
702 | |
703 It's possible to prefix a paragraph by one of the following topic, it renders a | |
704 different block depending on the output format: | |
705 | |
706 - Note: | |
707 - Warning: | |
708 - Danger: | |
709 | |
710 Then, if the paragraph is too long, indent the text correctly. | |
711 | |
712 ```markdown | |
713 Note: this is an information block that is too long to fit between the limits so | |
714 it is split and indented. | |
715 ``` |