/scc

Fork of git://git.simple-cc.org/scc

Primary LanguageCOtherNOASSERTION

Compiling
=========

SCC is a portable toolchain that can be compiled on any UNIX system
out of the box. It supports four main configuration options that
can be passed to the command line:

	- PREFIX: Prefix of the path where scc toolchain is going
	  to be installed. /usr/local by default.

	- LIBPREFIX: Prefix of the path where scc searchs for
	  headers and libraries when scc is executed. $PREFIX
	  by default.

	- DESTDIR: Temporary directory prepend to PREFIX used in the
	  install path. It is mainly intended to help package maintainers
	  to install in a specific directory used as base for the package
	  generation.

	- CROSS_COMPILE:
          Specify a prefix name for the tools called by the Makefile.

	- HOST:
	  Specify the host system to be used. Possible supported
	  values are:

		- unix (by default)
		- bsd
		- plan9

	- CONF: Specify which version of libc to build.
	  Once the build process completes only the target specified in
          CONF will be built. Supported values are:

		- amd64-linux (default)
		- amd64-darwin
		- amd64-openbsd
		- arm64-linux
		- amd64-dragonfly
		- amd64-freebsd
		- amd64-netbsd
		- arm32-linux
		- i386-linux

	  Not all the configurations have the same level of support in
	  the libc and in some cases the support is minimal.

	- TOOL: Specify the toolchain type to be used.  Possible
	  supported values are:

		- unix (by default)
		- gnu
		- gnu-darwin
		- clang

The main targets of the Makefile are:

	- all:
	  Compile the toolchain and the libc. It automatically
	  determines what is the best value for HOST. It sets the
	  value of CONF for the toolchain that is used by the
	  toolchain as the default target. It also compiles the libc
	  for all the available configurations based in the host
	  architecture.

	- config
	  Generate headers supposed to be customized by the user.

	- toolchain
	  Compile the toolchain with the default configuration
	  specified in CONF. Beware that this target is executed without
	  the automatic detection of the host parameters. It makes
	  easier to cross compile.

	- libc:
	  Compile the libc for the target specified in CONF. Beware
	  that this target is executed without the automatic detection
	  of the host parameters. It makes easier to cross compile.

	- install:
	  Installs scc in PREFIX.

	- clean:
	  Remove all the generated files except the one supposed to be edited
	  by the user.

	- distclean
	  Remove all the generated files.

Toolchain configuration
=======================
At this moment scc is still using some external tools to generate
the final binaries. The toolchain execution is configured in the
file `include/scc/scc/sys.h` and it included basically 5 elements:

	- LDBIN: macro with the name of the linker binary.

	- ASBIN: macro with the name of the assembler binary.

	- sysincludes: It is a list of diretories used to locate
	  the system headers

	- ldcmd: It describes how the linker command line is built.

	- ascmd: It describes how the assembler command line is built.

The definition of sysincludes, ldcmd and ascmd can include wildcards
represented by % followed by a single letter:

	- %c: It expands to the full list of input object files of the linker
	- %a: It expands to the architecture name
	- %s: It expands to the system name
	- %p: It expands to the library prefix
	- %b: It expands too the ABI name
	- %o: It expands to the output file of the current tool

Scc includes 3 configuration templates that can be used as base for the
configuration of the toolchain:

	- scc: It uses GNU assembler and linker with the scc libc.
	- scc_clang: It uses clang assembler and linker with the scc libc.
	- musl: It uses GNU assembler and linker with the musl libc.

The file `include/scc/scc/sys.h` is automatically created from the scc
toolchain configuration with the default make target. The target config
can be used to only create the file based on the value of the variable
`LIBPROFILE` allowing the user to customize that file as needed. It is
important to highlight that the file is not removed by `make clean`
because it can contain local user modifications. You should use
`make distclean` to remove it.


Musl libc support
=================
The scc libc is a C99 library and cannot be used to compile POSIX compliant
programs. Scc includes a template that can be used to use a musl libc
compiled by gcc:

	$ make LIBPROFILE=musl config

It will generate the files sys.h configured to be used with a musl
libc. Beware that it is likely that those files have to be customized to
fit your system because the macro GCCLIBPATH used by the musl template
depends heavily of the toolchain used to compile musl. As the musl libc
is likely installed in a different prefix the scc compilation must be
modified to:

	$ make LIBPREFIX=/usr/local/musl # point to the prefix used by your musl

If the helper scc shell script is used instead of scc-cc then the
environment variable SCCLIBPREFIX must be set:

	$ SCCLIBPREFIX=/usr/local/musl scc hello.c

Deviations from standard C
===========================
This compiler aims to be fully compatible with the C99 standard, but
it has some differences at this moment:

- Type qualifiers are accepted but partially ignored.
  --------------------------------------------------

The semantic behind them is not fully implemented, specially in the
case of volatile. Be aware that some programs can miswork for this
reason.

- Function type names
  -------------------

C99 allows you to define type names of function types and write something
like:

int f(int (int));

Accepting function types in type names (or abstract declarators) makes the
grammar ambiguous because it is impossible to differentiate between:

        (int (f))  -> function returning int with one parameter of type f
        (int (f))  -> integer variable f

If you don't believe me try this code:

int
f(int g())
{
	return g();
}

Function type names seem unnecesary , because they are used as
an alias of the function pointer types, but it is weird that something
like sizeof(int (int)) is not allowed (because here it should be
understood as the size of a function), but f(int (int)) is allowed
because it is understood as a parameter of function pointer type.

- Definition of variables with incomplete type
  ---------------------------------------------

C89 allows the definition of variables with incomplete type that
have external linkage and file scope. The type of the variable is the
composition of all the definitions found in the file. The exact rules
are a bit complex (ANSI 3.7.2, or ISO C99 6.2.5p22) so SCC ignores them
at this moment by simply not allowing any definition of variables with
incomplete type.

If you don't believe me try this code:

struct foo x;

struct foo {
	int i;
};

- Variadic function alike macros
  ------------------------------

The standard (C99 6.10.3 c 4) forces passing more parameters than
the number of parameters present in the variadic argument list
(excluding ...). SCC accepts a parameter list with the same number
of arguments.

#define P(a, ...) a

P(1)

C99 libc
========

The C99 libc only supports the C locale using UTF-8 for multibyte
sequences. It also assume that the wide character set includes as
ASCII as a subset.