README (6826B)
1 Compiling 2 ========= 3 4 SCC is a portable toolchain that can be compiled on any UNIX system 5 out of the box. It supports four main configuration options that 6 can be passed to the command line: 7 8 - PREFIX: Prefix of the path where scc toolchain is going 9 to be installed. /usr/local by default. 10 11 - LIBPREFIX: Prefix of the path where scc searchs for 12 headers and libraries when scc is executed. $PREFIX 13 by default. 14 15 - DESTDIR: Temporary directory prepend to PREFIX used in the 16 install path. It is mainly intended to help package maintainers 17 to install in a specific directory used as base for the package 18 generation. 19 20 - CROSS_COMPILE: 21 Specify a prefix name for the tools called by the Makefile. 22 23 - HOST: 24 Specify the host system to be used. Possible supported 25 values are: 26 27 - unix (by default) 28 - bsd 29 - plan9 30 31 - CONF: Specify which version of libc to build. 32 Once the build process completes only the target specified in 33 CONF will be built. Supported values are: 34 35 - amd64-linux (default) 36 - amd64-darwin 37 - amd64-openbsd 38 - arm64-linux 39 - amd64-dragonfly 40 - amd64-netbsd 41 - arm32-linux 42 - i386-linux 43 44 - TOOL: Specify the toolchain type to be used. Possible 45 supported values are: 46 47 - unix (by default) 48 - gnu 49 - gnu-darwin 50 - clang 51 52 The main targets of the Makefile are: 53 54 - all: 55 Compile the toolchain and the libc. It automatically 56 determines what is the best value for HOST. It sets the 57 value of CONF for the toolchain that is used by the 58 toolchain as the default target. It also compiles the libc 59 for all the available configurations based in the host 60 architecture. 61 62 - config 63 Generate headers supposed to be customized by the user. 64 65 - toolchain 66 Compile the toolchain with the default configuration 67 specified in CONF. 68 69 - libc: 70 Compile the libc for the target specified in CONF. 71 72 - install: 73 Installs scc in PREFIX. 74 75 - clean: 76 Remove all the generated files except the one supposed to be edited 77 by the user. 78 79 - distclean 80 Remove all the generated files. 81 82 Musl libc support 83 ================= 84 The Scc libc is a C99 library and cannot used to compile POSIX compliant 85 programs. Scc includes a template that can be used to use a musl libc 86 compiled by gcc: 87 88 $ make LIBPROFILE=musl config 89 90 It will generate the files sysld.h and sysincludes.h configured to be used 91 with a musl libc. Beware that it is likely that those files have to be 92 customized to fit your system because the macro GCCLIBPATH depends heavily 93 of the toolchain used to compile musl. As the musl libc is likely 94 will be installed in a different prefix the scc compilation must be modified 95 to: 96 97 $ make LIBPREFIX=/usr/local/musl 98 99 If the helper scc shell script is used instead of scc-cc then the 100 environment variable SCCLIBPREFIX must be set: 101 102 $ SCCLIBPREFIX=/usr/local/musl scc hello.c 103 104 Deviations from standard C 105 =========================== 106 This compiler aims to be fully compatible with the C99 standard, but 107 it will have some differences: 108 109 - Type qualifiers are accepted but ignored. 110 ----------------------------------------- 111 112 Type qualifiers make the type system more complex and they add 113 unnecessary complexity to the compiler (and increased compilation time): 114 115 - const: The definition of const is not clear in the standard. 116 If a const value is modified the behavior is undefined 117 behaviour. It seems it was defined in order to be able to 118 allocate variables in ROM rather than error detection. This 119 implememtation will not warn about these modifications and 120 the compiler will treat them like normal variables (the standard 121 specifies that a diagnostic message must be printed). 122 123 - volatile: This qualifier was added to the standard 124 to be able to deal with longjmp (local variables that are not 125 volatile have undefined state) and for memory mapped registers 126 or variables whose values are modified asynchronously. This can 127 be achieved by using special pragma values though. 128 In the first case, it generates a lot of problems with modern 129 processors and multithreading, when not holding the value in a 130 register is not good enough (an explicit memory barrier is needed). 131 In the second case, this is non-portable code by definition 132 (depending on the register mapped), so it is better to deal with 133 it using another solution (compiler extensions or direct 134 assembly). Since it is needed for the correct behaviour 135 of portable programs that use longjmp, this specifier eventually 136 will be implemented. 137 138 - restrict: This qualifier can only be applied to pointers that 139 mark the pointed object and has no other alias. This qualifier 140 was introduced to be able to fix some performance problems in 141 numerical algorithms, where FORTRAN could achieve a better 142 performance (and in fact even with this specifier FORTRAN has a 143 better performance in this field). Ignoring it doesn't make the 144 compiler non-standard and in almost all applications the performance 145 will be the same. 146 147 - Function type names 148 ------------------- 149 150 C99 allows you to define type names of function types and write something 151 like: 152 153 int f(int (int)); 154 155 Accepting function types in type names (or abstract declarators) makes the 156 grammar ambiguous because it is impossible to differentiate between: 157 158 (int (f)) -> function returning int with one parameter of type f 159 (int (f)) -> integer variable f 160 161 If you don't believe me try this code: 162 163 int 164 f(int g()) 165 { 166 return g(); 167 } 168 169 Function type names are stupid, because they are used as an alias 170 of the function pointer types, but it is stupid that something 171 like sizeof(int (int)) is not allowed (because here it should be 172 understood as the size of a function), but f(int (int)) is allowed 173 because it is understood as a parameter of function pointer type. 174 175 This complexity is not needed at all as function pointers fix all these 176 problems without this complexity (and they are the more common 177 way of writing such code). 178 179 - Definition of variables with incomplete type 180 --------------------------------------------- 181 182 C89 allows the definition of variables with incomplete type that 183 have external linkage and file scope. The type of the variable is the 184 composition of all the definitions found in the file. The exact rules 185 are a bit complex (ANSI 3.7.2, or ISO C99 6.2.5p22) so SCC ignores them 186 at this moment by simply not allowing any definition of variables with 187 incomplete type. 188 189 If you don't believe me try this code: 190 191 struct foo x; 192 193 struct foo { 194 int i; 195 }; 196 197 - Variadic function alike macros 198 ------------------------------ 199 200 The standard (C99 6.10.3 c 4) forces passing more parameters than 201 the number of parameters present in the variadic argument list 202 (excluding ...). SCC accepts a parameter list with the same number 203 of arguments. 204 205 #define P(a, ...) a 206 207 P(1)