From 4bfd158f068d63065e4989ded83124de55b309ff Mon Sep 17 00:00:00 2001 From: Roland Hieber Date: Wed, 20 Mar 2019 15:01:42 +0100 Subject: remove leftovers from libabc skeleton MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Additionally, remove the confusing disclaimer that this is public domain software (which applies to the libabc template, not libdt or dt-utils – we have COPYING for that). Signed-off-by: Roland Hieber --- README | 257 --------------------------------------------------------- src/.gitignore | 2 - 2 files changed, 259 deletions(-) diff --git a/README b/README index 9d5d50c..cdd32a6 100644 --- a/README +++ b/README @@ -1,262 +1,5 @@ -/* - This is free and unencumbered software released into the public domain. - - Anyone is free to copy, modify, publish, use, compile, sell, or - distribute this software, either in source code form or as a compiled - binary, for any purpose, commercial or non-commercial, and by any - means. - - In jurisdictions that recognize copyright laws, the author or authors - of this software dedicate any and all copyright interest in the - software to the public domain. We make this dedication for the benefit - of the public at large and to the detriment of our heirs and - successors. We intend this dedication to be an overt act of - relinquishment in perpetuity of all present and future rights to this - software under copyright law. - - Unless you really want to, do not even mention that the copied content - originates from this skeleton library. Its sole purpose is to be copied - into other projects. - - The above statements apply to all content in this skeleton library, even - when the COPYING files, or the headers in the files state otherwise, - they are just common examples. -*/ - Questions, feedback, patches please email: oss-tools@pengutronix.de For patches, please prefix your subject with "[PATCH dt-utils]" (for example, see the git-config manpage for the option format.subjectPrefix). - -Why bother? - - To make things easy for library users, distribution packagers and - developers of library bindings for other programming languages. If - you want your stuff to be used and commonly available, try to play - nice, and give them what they are used to. It makes their life a - lot easier. - -use autotools - - Every custom config/makefile/build system is worse for everybody - than autotools is. - - We are all used to autotools, it works, nobody cares. - - It's only two simple files to edit and include in git, which are - well understood by many many people, not just you. - - Ignore all crap autotools create in the source tree. never check - the created files into git. - - Never, ever, install config.h. That's internal to your sources - and is nothing to install. - - And really, anything but autotools is realy an option. Just get - over it. Everything else is an experiment, and it will come back - to you sooner or later. Why? think cross compilation, installation/ - uninstallation, build root integration, separate object trees, - standard adherence, tarball handling, make distcheck, testing, - portability between distros, ... - -If you use the GPL, always use the GPL's "(or later)" clause - - Developers are not lawyers, libraries should be able to be linked - to any version of the GPL. Remember that GPL2-only is incompatible - with LGPL3! - -Use LGPL (for the shared libraries) if you don't care about politics - - It protects the code, but does not restrict its use. Low-level - library interfaces are mostly used like kernel syscall or proc/sysfs - interfaces, which are usually without any restrictions. - -Zero global state -- Make your library threads-aware, but *not* thread-safe! - - An app can use liba and libb. libb internally can also use liba -- - without you knowing. Both you and libb can run liba code at the - very same time in different threads and operate at the same global - variables, without telling you about that. Loadable modules make - this problem even more prominent, since the libraries they pull in - are generally completely unknown by the main application. And - *every* program has loadable modules, think NSS! - - Avoid locking and mutexes, they are very unlikely to work correctly, - and incredibly hard to get right. - - Always use a library context object. every thread should then - operate on its own context. Do not imply context objects via TLS. It - won't work. TLS inheritance to new threads will get in your way. TLS - is a problem in itself, not a solution. - - Do not use gcc constructors, or destructors, you can only loose if - you do. Do not use _fini() or _ini(), don't even use your own - explicit library initializer/destructor functions. It just won't - work if your library is pulled in indirectly from another library - or even a shared module (i.e. dlopen()) - - Always use O_CLOEXEC, SOCK_CLOEXEC and friends. It's not an - option, it's a must. - - Don't use global variables (it includes static variables defined - inside functions). Ever. And under no circumstances export global - variables. It's madness. - -Use a common prefix for _all_ exported symbols - - Avoids namespace clashes - - Also, hacking is not a contest of finding the shortest possible - function name. And nobody cares about your 80ch line limit! - - If you use a drop-in library in your own library make sure to hide its - symbols with symbol versioning. Don't forget to hide *all* symbols, and - don't install the header file of the used drop-in library. - -Do not expose any complex structures in your API - - Use get() and set() instead. - - All objects should be opaque. - - Exporting structs in headers is OK in very few cases only: usually - those where you define standard binary formats (think: file - formats, datagram headers, ...) or where you define well-known - primitive types (think struct timeval, struct iovec, uuid - type). - - Why bother? Because struct stat, struct dirent and friends are - disasters. Particularly horrible are structs with fixed-size - strings. - -Use the de-facto standardized function names - - It's abc_new(), abc_free(), abc_ref(), abc_unref(). Don't invent - your own names, and don't use the confusing kernel-style ref - counting. Function names: _get() is for accessing properties of - objects, not for refcounting. - -Stick to kernel coding style - - Just because you are otherwise not bound by the kernel guidelines - when your write userspace libraries doesn't mean you have to give - up the good things it defines. - -Avoid callbacks in your API - - Language bindings want iterators. - - Programmers want iterators too. - -Never call exit(), abort(), be very careful with assert() - - Always return error codes. - - Libraries need to be safe for usage in critical processes that - need to recover from errors instead of getting killed (think PID 1!). - -Avoid thinking about main loops/event dispatchers. - - Get your stuff right in the kernel: fds are awesome, expose them - in userspace and in the library, because people can easily integrate - them with their own poll() loops of whatever kind they have. - - Don't hide file descriptors away in your headers. - - Never add blocking kernel syscalls, and never add blocking library - calls either (with very few exceptions). Userspace code is primarily - asynchronous around event loops, and blocking calls are generally - incompatible with that. - - Corollary of that: always O_NONBLOCK! - -Functions should return int and negative errors instead of NULL - - Return NULL in malloc() is fine, return NULL in fopen() is not! - - Pass allocated objects as parameter (yes, ctx_t** is OK!) - - Returning kernel style negative error codes is cool in - userspace too. Do it! - -Provide pkgconfig files - - Apps want to add a single line to their configure file, - they do not want to fiddle with the parameters, dependencies - to setup and link your library. - - It's just how we do these things today on Linux, and everything - else is just horribly messy. - -Avoid *hidden* fork()/exec() in libraries - - Apps generally do not expect signals and react allergic to them. - - Mutexes, locks, threads of the app might get confused. Mixing - mutexes and fork() equals failure. It just can't work, and - pthread_atfork() is not a solution for that, because it's broken - (even POSIX acknowledges that, just read the POSIX man - pages!). fork() safety for mutex-ridden code is not an - afterthought, it's a broken right from the beginning. - -Make your code safe for unexpected termination and any point: - - Do not leave files dirty or temporary files around. - - This is a tricky, since you need to design your stuff like this - from the beginning, it's not an afterthought, since you generally - do not have a place to clean up your stuff on exit. gcc - destructors are NOT the answer. - -Use symbol versioning - - Only with that, RPM can handle dependencies for added symbols - - Hide all internal symbols! *This is important!* - -Always provide logging/debugging, but do not clutter stderr - - Allow the app to hook the libs logging into its logging facility. - - Use conditional logging, do not filter too late. - - Do not burn cycles with printf() to /dev/null. - - By default: do not generate any output on stdout/stderr. - -Always use 'make distcheck' to create tarballs - - Never release anything that does not pass distcheck. It will - likely be broken for others too - -Use ./autogen.sh to bootstrap the git repo - - Always test bootstrapping with 'git clean -x -f -d' before - release (careful, it force-deletes all uncommitted files). - -Avoid any spec files or debian/ subdirs in git trees - - Distribution specific things do not belong in upstream trees, - but into distro packages - -Update NEWS to let developers know what has changed - - It's the history of the project, stuff that packagers need to know - when putting a new version in the distro. The interesting changes - or added/removed functionality from version to version. This is - not a commit changelog. - - If you want to provide ChangeLog, use the one generated - by git, do not maintain your own. - -use standard types - - The kernel's u8, u16, ... correspond to uint8_t, uint16_t in - userspace from . Don't define your own typedefs - for that, don't include the kernel types in common headers. - - Use enums, not #define for constants, wherever possible. In - userspace you have debuggers, and they are much nicer to use if - you have proper enum identifiers instead of macro definitions, - because the debugger can translate binary values back to enum - identifiers, but not macros. However, be careful with enums in - function prototypes: they might change the int type they are - resolved to as you add new enum values. - -Always guard for multiple inclusions of headers - - You must place '#ifndef libabc, #define libabc, #endif' in your - header files. There is no way around that. - -Be careful with variadic functions - - It's great if you provide them, but you must accompany them with - "v" variants (i.e. functions taking a va_arg object), and provide - non-variadic variants as well. This is important to get language - wrappers right. - -Don't put "extern" in front of your function prototypes in headers - - It has no effect, no effect at all. - -Never use sysv IPC, always use POSIX IPC - - Shmops and semops are horrors. Don't use them, ever. POSIX IPC is - much much much nicer. - -Avoid multiplexed functions ala ioctl()/prctl() style variadic functions - - Type-safety is awesome! - -Executing out-of-process tools and parsing their output is usually -not acceptable in libraries - - Tools should be built on top of their own lib. - - Always separate 'mechanism' from 'policy'. Make access to functionality - simple, but do not try to hide things that need to be decided by the - caller. Keep automagic at its minimum. Don't do hidden fork() do not - implicitly maintain cache files, ... - -Function calls with 15 arguments are a bad idea. If you have tons of -booleans in a function call, then replace them by a flag argument! - - Think about the invocation! foo(0, 1, 0, 1, 0, 0, 0, 1) is unreadable! - foo(FOO_QUUX|FOO_BAR|FOO_WALDO) much nicer. - -Don't be afraid of C99. Use it. - - It's 12 years old. And it's nice. - -Never expose fixed size strings in your API - - Pass malloc()ed strings out, or ask the caller to provide you with - a buffer, and return ENOSPC if too short. - -Glibc has byteswapping calls, don't invent your own: - - le32toh(), htole32() all those are documented in endian(3) - - bswap_32(), bswap_16(), bswap_64(). #include - - Don't use the versions provided by the linux kernel headers cpu_to_*() , *_to_cpu. - stick to the glibc API. - -Don't typedef pointers to structs! - -Don't write your own LISP interpreter and do not include it in your -library. :) diff --git a/src/.gitignore b/src/.gitignore index 5e25d6d..088ef79 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -3,5 +3,3 @@ .libs/ *.la *.lo -libabc.pc -test-libabc -- cgit v1.2.3