[build] Move headers out of target dirs

The great header shift: It didn't make sense to regenerate headers for
the same module for every target (boot/kernel/user) it appeared in. And
now that core headers are out of src/include, this was going to cause
problems for the new libc changes I've been working on. So I went back
to re-design how module headers work.

Pre-requisites:
- A module's public headers should all be available in one location, not
  tied to target.
- No accidental includes. Another module should not be able to include
  anything (creating an implicit dependency) from a module without
  declaring an explicit dependency.
- Exception to the previous: libc's headers should be available to all,
  at least for the freestanding headers.

New system:
- A new "public_headers" property of module declares all public headers
  that should be available to dependant modules
- All public headers (after possible processing) are installed relative
  to build/include/<module> with the same path as their source
- This also means no "include" dir in modules is necessary. If a header
  should be included as <j6/types.h> then its source should be
  src/libraries/j6/j6/types.h - this caused the most churn as all public
  header sources moved one directory up.
- The "includes" property of a module is local only to that module now,
  it does not create any implicit public interface

Other changes:
- The bonnibel concept of sources changed: instead of sources having
  actions, they themselves are an instance of a (sub)class of Source,
  which provides all the necessary information itself.
- Along with the above, rule names were standardized into <type>.<ext>,
  eg "compile.cpp" or "parse.cog"
- cog and cogflags variables moved from per-target scope to global scope
  in the build files.
- libc gained a more dynamic .module file
This commit is contained in:
Justin C. Miller
2022-02-06 10:18:51 -08:00
parent db23e4966e
commit 4545256b49
103 changed files with 362 additions and 5191 deletions

View File

@@ -0,0 +1,86 @@
#pragma once
/* Signal handling <string.h>
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include "j6libc/config.h"
#include "j6libc/cpp.h"
#include "j6libc/sig_atomic_t.h"
CPP_CHECK_BEGIN
/* Signals ------------------------------------------------------------------ */
/* A word on signals, to the people using PDCLib in their OS projects.
The definitions of the C standard leave about everything that *could* be
useful to be "implementation defined". Without additional, non-standard
arrangements, it is not possible to turn them into a useful tool.
This example implementation chose to "not generate any of these signals,
except as a result of explicit calls to the raise function", which is
allowed by the standard but of course does nothing for the usefulness of
<signal.h>.
A useful signal handling would:
1) make signal() a system call that registers the signal handler with the OS
2) make raise() a system call triggering an OS signal to the running process
3) make provisions that further signals of the same type are blocked until
the signal handler returns (optional for SIGILL)
*/
/* These are the values used by Linux. */
/* Abnormal termination / abort() */
#define SIGABRT 6
/* Arithmetic exception / division by zero / overflow */
#define SIGFPE 8
/* Illegal instruction */
#define SIGILL 4
/* Interactive attention signal */
#define SIGINT 2
/* Invalid memory access */
#define SIGSEGV 11
/* Termination request */
#define SIGTERM 15
typedef void (*sighandler_t)(int);
/* The following should be defined to pointer values that could NEVER point to
a valid signal handler function. (They are used as special arguments to
signal().) Again, these are the values used by Linux.
*/
#define SIG_DFL (sighandler_t)0
#define SIG_ERR (sighandler_t)-1
#define SIG_IGN (sighandler_t)1
/* Installs a signal handler "func" for the given signal.
A signal handler is a function that takes an integer as argument (the signal
number) and returns void.
Note that a signal handler can do very little else than:
1) assign a value to a static object of type "volatile sig_atomic_t",
2) call signal() with the value of sig equal to the signal received,
3) call _Exit(),
4) call abort().
Virtually everything else is undefind.
The signal() function returns the previous installed signal handler, which
at program start may be SIG_DFL or SIG_ILL. (This implementation uses
SIG_DFL for all handlers.) If the request cannot be honored, SIG_ERR is
returned and errno is set to an unspecified positive value.
*/
sighandler_t signal( int sig, sighandler_t func );
/* Raises the given signal (executing the registered signal handler with the
given signal number as parameter).
This implementation does not prevent further signals of the same time from
occuring, but executes signal( sig, SIG_DFL ) before entering the signal
handler (i.e., a second signal before the signal handler re-registers itself
or SIG_IGN will end the program).
Returns zero if successful, nonzero otherwise. */
int raise( int sig );
CPP_CHECK_END