libk  Check-in [37b0cfaa06]

Overview
Comment:revamp arch/ makefile, add generic syscall fn on posix, rewrite kiosend() to use k_platform_syscall instead of k_platform_write
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 37b0cfaa06fd213a266dd24f1a6b482accb59f1be3ec0c99d7ba430c7a70afe4
User & Date: lexi on 2019-08-18 17:56:41
Other Links: manifest | tags
Context
2019-08-18
18:29
add error reporting to kiosend() check-in: b2f129d7b9 user: lexi tags: trunk
17:56
revamp arch/ makefile, add generic syscall fn on posix, rewrite kiosend() to use k_platform_syscall instead of k_platform_write check-in: 37b0cfaa06 user: lexi tags: trunk
13:42
add functions, generate C syscall table check-in: a8d93823f1 user: lexi tags: trunk
Changes

Modified arch/makefile from [21471ec514] to [ce87fe2fb7].



















1
2
3
4


5
6
7
8


9
10
11

12
13
14
15









16
17
18
19


















${TMP}:
	mkdir -p ${TMP}

${TMP}/calls.x86.lin.32.tbl: ${lin-headers}/unistd_32.h ${TMP}


	grep "#define __NR_" $< | sed 's;^#define __NR_;;' > $@
${TMP}/calls.x86.lin.64.tbl: ${lin-headers}/unistd_64.h ${TMP}
	grep "#define __NR_" $< | sed 's;^#define __NR_;;' > $@
${TMP}/calls.x86.fbsd.%.tbl: ${fbsd-headers}/syscall.h ${TMP}


	grep "#define	SYS_" $< | sed 's;^#define	SYS_;;' | sed 's;[\t ]\+; ;' > $@

${TMP}/calls.s: ${TMP}/calls.${TARGET}.tbl

	awk -f syscall.awk -v out=asm <$< >$@
${TMP}/calls.h: ${TMP}/calls.${TARGET}.tbl
	awk -f syscall.awk -v out=header <$< >$@










${TMP}/typesize: typesize.c
	$(CC) -std=c11 $< -o $@
${TMP}/typesize.def: ${TMP}/typesize
	$< > $@
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



<
>
>
|
<
<
<
>
>
|

<
>
|
<
<

>
>
>
>
>
>
>
>
>
|

|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

22
23
24



25
26
27
28

29
30


31
32
33
34
35
36
37
38
39
40
41
42
43
44
ifeq (${OS},lin)
    p-headers-syscall ?= /usr/include/asm/unistd_${BITS}.h
    p-headers-errno ?= /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h
else ifeq (${OS},fbsd)
    p-headers-syscall ?= /usr/include/sys/syscall.h
    p-headers-errno ?= /usr/include/errno.h
else
    $(info we don’t know where to find your magic number headers.)
    $(info to compile libk, please provide the following variables \
to the make command line:)
    $(info --- p-headers-syscall=(location of syscall header))
    $(info --- p-headers-errno=(location of your errno values header))
    $(info note that /usr/include/errno.h or your system’s equivalent \
may not be sufficient. make sure the file you pass actually contains \
individual #define statements for each possible value of errno!)
    $(error table generation failed due to missing primaries)
endif

${TMP}:
	mkdir -p ${TMP}


${TMP}/calls.lin@x86.%.tbl: $(p-headers-syscall) 
	mkdir -p ${TMP}
	grep -h "#define __NR_" $^ | sed 's;^#define __NR_;;' > $@



${TMP}/calls.fbsd@%.tbl: $(p-headers-syscall) 
	mkdir -p ${TMP}
	grep -h "#define	SYS_" $^ | sed 's;^#define	SYS_;;' | sed 's;[\t ]\+; ;' > $@


${TMP}/system_calls.%: ${TMP}/calls.${OS}@${ARCH}.${BITS}.tbl ${TMP}
	awk -f syscall.awk -v out=$* <$< >$@



${TMP}/error_names.tbl: $(p-headers-errno)
	mkdir -p ${TMP}
	grep -h "#[	 ]*define[ 	]\+E" $^ | sed 's;^#[\t ]*define[\t ]\+\(E[A-Z0-9]\+\).*$$;k_platform_error_\1 \1;' > $@
${TMP}/error_numbers.tbl: $(p-headers-errno) ${TMP}/error_names.tbl
	cat $^ | cpp -P >$@

${TMP}/error_table.h: ${TMP}/error_numbers.tbl ${TMP}
	awk -f errtbl.awk <$< >$@

${TMP}/typesize: typesize.c ${TMP}
	$(CC) -std=c11 $< -o $@
${TMP}/typesize.def: ${TMP}/typesize ${TMP}
	$< > $@

Modified arch/posix.h from [7d3483dee1] to [b77089e7ab].

1
2
3
4
5
6
7


8
9
10
11
12
13
14
..
28
29
30
31
32
33
34
35
36
37


























/* arch/posix.h - posix constants
 *  ? this file defines posix magic numbers
 *    needed in syscalls, both cross-platform
 *    ones and os-dependent ones. note that
 *    the values may change depending on the
 *    OS specified! */



#include <k/def.h>
#include <k/type.h>

enum posix_prot {
	posix_prot_none  = 0,
	posix_prot_read  = 1 << 0,
	posix_prot_write = 1 << 1,
................................................................................
	posix_flag_anonymous = 0x1000,
#endif

	/* platform flags */
	posix_flag_linux_hugetlb = 0x40000
};

struct kposix_syscall_result { long ret, error; }

kposix_syscall(enum kposix_syscall syscall, sz argct, long args[]);

































>
>







 







|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/* arch/posix.h - posix constants
 *  ? this file defines posix magic numbers
 *    needed in syscalls, both cross-platform
 *    ones and os-dependent ones. note that
 *    the values may change depending on the
 *    OS specified! */

#ifndef KIplatform_posix
#define KIplatform_posix
#include <k/def.h>
#include <k/type.h>

enum posix_prot {
	posix_prot_none  = 0,
	posix_prot_read  = 1 << 0,
	posix_prot_write = 1 << 1,
................................................................................
	posix_flag_anonymous = 0x1000,
#endif

	/* platform flags */
	posix_flag_linux_hugetlb = 0x40000
};

/* platform types */

typedef s64 k_platform_syscall_return;
typedef u64 k_platform_syscall_error;

#if KVos == KA_os_lin
	typedef long k_platform_syscall_arg;
#elif KVos == KA_os_fbsd
	typedef u64  k_platform_syscall_arg;
#else
	/* we're going to just pick a sane
	 * fallback that's reasonably likely
	 * to work with most systems one way
	 * or another */
	typedef unsigned long long k_platform_syscall_arg;
#endif

struct k_platform_syscall_answer {
	k_platform_syscall_return ret;
	k_platform_syscall_error error;
};

#include <system_calls.h>

extern struct k_platform_syscall_answer
k_platform_syscall(enum k_platform_syscall call, u8 valency, 
		k_platform_syscall_arg args[]);

#endif

Modified arch/syscall.awk from [5422b4d7e5] to [23075063af].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
BEGIN {
	if (out == "header") {
		print "#ifndef KIplatform_syscalls"
		print "#define KIplatform_syscalls"
		print "enum /* syscall numbers */ {"
	}
}

out == "header" { print "\tk_platform_syscall_"$1" = "$2"," }
out == "asm"    { print "%define sys."$1" "$2 }

END {
	if (out == "header") {
		print "}"
		print "#endif"
	}
}

|


|



|
|


|
|



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
BEGIN {
	if (out == "h") {
		print "#ifndef KIplatform_syscalls"
		print "#define KIplatform_syscalls"
		print "enum k_platform_syscall {"
	}
}

out == "h" { print "\tk_platform_syscall_"$1" = "$2"," } # c header
out == "s" { print "%define sys."$1" "$2 } # assembly

END {
	if (out == "h") {
		print "};"
		print "#endif"
	}
}

Modified arch/x86.fbsd.32.s from [c5f65471b5] to [fb0cced6da].

1
2
3
4
5
6
7
8
9
10
11
12
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm

; syscall numbers - syscall table must be created first!
%include "calls.s"

; extremely stupid freebsd-ism: expects the syscall to
; come from a function
_syscall: int 0x80
          ret

%define sys.call call _syscall




|







1
2
3
4
5
6
7
8
9
10
11
12
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm

; syscall numbers - syscall table must be created first!
%include "system_calls.s"

; extremely stupid freebsd-ism: expects the syscall to
; come from a function
_syscall: int 0x80
          ret

%define sys.call call _syscall

Modified arch/x86.fbsd.64.s from [ef3e7f83e4] to [8f1b903740].

1
2
3
4
5
6
7
8
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm

; syscall numbers - syscall table must be created first!
%include "calls.x86.fbsd.64.s"

; freebsd uses the common x86-64 ABI
%include "x86.syscall.64.s"




|



1
2
3
4
5
6
7
8
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm

; syscall numbers - syscall table must be created first!
%include "system_calls.s"

; freebsd uses the common x86-64 ABI
%include "x86.syscall.64.s"

Modified arch/x86.lin.32.s from [cef64f4a20] to [d3081be9ee].

1
2
3
4
5
6
7
8
9
10
11
12
;; abi definition file for x86 linux 32-bit
; vim: ft=nasm

; syscall32 numbers - syscall table must be created first!
%include "calls.s"

; syscall32 registers
%define sys.reg.n 6
%define sys.reg.0 eax
%define sys.reg.1 ebx
%define sys.reg.2 ecx
%define sys.reg.3 edx




|







1
2
3
4
5
6
7
8
9
10
11
12
;; abi definition file for x86 linux 32-bit
; vim: ft=nasm

; syscall32 numbers - syscall table must be created first!
%include "system_calls.s"

; syscall32 registers
%define sys.reg.n 6
%define sys.reg.0 eax
%define sys.reg.1 ebx
%define sys.reg.2 ecx
%define sys.reg.3 edx

Modified arch/x86.lin.64.s from [2072c8d435] to [a477b8d971].

1
2
3
4
5
6
7
8
9
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm

; syscall64 numbers - syscall table must be created first!
%include "calls.s"

; linux uses the common x86-64 ABI
%include "x86.syscall.64.s"





|




1
2
3
4
5
6
7
8
9
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm

; syscall64 numbers - syscall table must be created first!
%include "system_calls.s"

; linux uses the common x86-64 ABI
%include "x86.syscall.64.s"

Modified arch/x86.syscall.64.s from [43eb022a86] to [b26026b9a4].

25
26
27
28
29
30
31

32
33
34
35
36
37
38
39

; syscall ops
%define sys.call syscall

; register order for syscall convention
%define sys.reg.n 7
%define sys.reg.ret rax

%define sys.reg.0 rax
%define sys.reg.1 rdi
%define sys.reg.2 rsi
%define sys.reg.3 rdx
%define sys.reg.4 r10
%define sys.reg.5 r8
%define sys.reg.6 r9








>








25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

; syscall ops
%define sys.call syscall

; register order for syscall convention
%define sys.reg.n 7
%define sys.reg.ret rax
%define sys.reg.err rbx
%define sys.reg.0 rax
%define sys.reg.1 rdi
%define sys.reg.2 rsi
%define sys.reg.3 rdx
%define sys.reg.4 r10
%define sys.reg.5 r8
%define sys.reg.6 r9

Modified kcore/exit.fn.x86.lin.64.s from [4c49f79d26] to [c7202f2e83].

1
2
3
4
5
6
7
8
9
10
11
bits 64
%include "../arch/x86.lin.64.s"
%include "../arch/x86.cdecl.64.s"
; vim: ft=nasm

global kio_posix_exit
kio_posix_exit:
	mov sys.reg.1, ccall.reg.0 ;nop - rdi → rdi
	mov sys.reg.0, sys.exit
	sys.call
	; no return





|





1
2
3
4
5
6
7
8
9
10
11
bits 64
%include "../arch/x86.lin.64.s"
%include "../arch/x86.cdecl.64.s"
; vim: ft=nasm

global kio_posix_exit:function
kio_posix_exit:
	mov sys.reg.1, ccall.reg.0 ;nop - rdi → rdi
	mov sys.reg.0, sys.exit
	sys.call
	; no return

Added kcore/platform.syscall.fn.c version [4315e80d93].









































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/* platform.syscall.fn.c
 * ~ lexi hale <lexi@hale.su>
 * this file provides a unified interface
 * to the host operating system's syscalls.
 * its function signature may vary across
 * OSes, as the details of each's syscall
 * implementation may vary drastically.
 */

#include <k/def.h>
#include <k/type.h>

#ifdef KFenv_posix
#	include <posix.h>
#else
	Knoimpl(k_platform_syscall)
#endif

extern void k_platform_syscall_raw (
		k_platform_syscall_return* return_slot,
		k_platform_syscall_error*  error_no_slot,
		enum k_platform_syscall    syscall_no,
		u8                         valency,
		s64*                       args);

struct k_platform_syscall_answer
k_platform_syscall(enum k_platform_syscall call, u8 valency, s64 args[]) {
	struct k_platform_syscall_answer answer;

	k_platform_syscall_raw
		(&answer.ret,
		 &answer.error,
		 call, valency, args);

	return answer;
}

Added kcore/syscall.fn.x86.lin.64.s version [f9a360108d].



















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
; kcore/syscall.fn.x86.lin.64.s
; ~ lexi hale <lexi@hale.su>
;
; this function performs a syscall and stores its
; results in the variables provided. this makes it
; possible to bypass the hideous errno mechanism
; altogether and access the error value of a
; syscall directly. invoke as:
;
; 	void k_platform_syscall_raw(s64* result, u64* errno,
;		syscall, u8 valency, s64[] args)

bits 64
%include "../arch/x86.lin.64.s"
%include "../arch/x86.cdecl.64.s"
; vim: ft=nasm

%macro handle_arg 1
	%assign v %1+1
	mov sys.reg. %+ v, [ccall.reg.4 + 8 * %1]
	dec ccall.reg.3
	jz .perform_call
%endmacro

global k_platform_syscall_raw:function
k_platform_syscall_raw:
	; locals: rbx = s64* result
	;         r12 = u64* errno
	; arg 0 = s64* result
	; arg 1 = errno ptr
	; arg 2 = syscall num
	; arg 3 = valency
	; arg 4 = args ptr

	; store the locals in registers that
	; are guaranteed not to be clobbered,
	; saving us some cycles pushing to
	; and popping back from the stack
	mov rbx, ccall.reg.0
	mov r12, ccall.reg.1

	; this needs to go before the loop
	; or it'll get clobbered
	mov sys.reg.0, ccall.reg.2

	; automatically generate the code
	; needed to move the arguments into
	; their correct registers. see above
	%assign i 0
	%rep 6
		handle_arg i
		%assign i i+1
	%endrep

	; valency >= 7. this is not valid, so
	; we set our return value to 0 and the
	; error number to its maximum value in
	; order to indicate that the syscall
	; was invalid
	mov qword [rbx], 0
	mov qword [r12], -1
	ret

	; we have a valency match - perform the
	; requested syscall already store in rax
	.perform_call: sys.call
	
	; move our return values into place and
	; return to the caller (which should
	; always be k_platform_syscall, btw)
	mov [rbx], sys.reg.ret
	mov [r12], sys.reg.err
	ret

Modified kio/send.fn.c from [5cc5cc2649] to [0bd4793a38].

6
7
8
9
10
11
12
13
14
15
16
17
18
19









20
21
22
23
24
25
26
27
28
29
30
31
32
 * kiosend() writes to a channel with an open out stream
 */

/* we define all platform functions here,
 * whether or not they're for the correct
 * platform - only the ones actually called
 * by the generated code will be linked */
extern sz kio_posix_fd_write(int fd, const char* buf, sz len);

kiocond kiosend(kiochan target, ksraw string, sz* len) {
	if (target.out.kind == kiostream_closed) return kiocond_fail_closed_stream;

#	ifdef KFenv_posix
		sz size = kio_posix_fd_write(target.out.platform_fd, string.ptr, string.size);









		if (size == -1) return kiocond_fail; //TODO: retrieve errno and offer more specific errors
#	else
#		if KVos == win
#			error windows IO send function not yet defined
#		else
			Knoimpl(kiosend,KVos);
#			error missing implementation // boring error for plebs
#		endif
#	endif

	if (len != null) *len = size;
	return kiocond_ok;
}







|





|
>
>
>
>
>
>
>
>
>













6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 * kiosend() writes to a channel with an open out stream
 */

/* we define all platform functions here,
 * whether or not they're for the correct
 * platform - only the ones actually called
 * by the generated code will be linked */
#include <posix.h>

kiocond kiosend(kiochan target, ksraw string, sz* len) {
	if (target.out.kind == kiostream_closed) return kiocond_fail_closed_stream;

#	ifdef KFenv_posix
		/* issue the write syscall here and now so we can
		 * retrieve errno and report it if necessary */

		k_platform_syscall_arg args[] = {
			target.out.platform_fd, (k_platform_syscall_arg)string.ptr, string.size };

		struct k_platform_syscall_answer a = k_platform_syscall
			(k_platform_syscall_write,3,args);

		sz size = a.ret;
		if (size == -1) return kiocond_fail; //TODO: retrieve errno and offer more specific errors
#	else
#		if KVos == win
#			error windows IO send function not yet defined
#		else
			Knoimpl(kiosend,KVos);
#			error missing implementation // boring error for plebs
#		endif
#	endif

	if (len != null) *len = size;
	return kiocond_ok;
}

Modified makefile from [47b194b965] to [5163613e5d].

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
ifneq ($(BITS),)
    export TARGET = $(ARCH).$(OS).$(BITS)
else
    export TARGET = $(ARCH).$(OS)
endif

export m4 = m4
export lin-headers = /usr/include/asm
export fbsd-headers = /usr/include/sys

moddirs = $(wildcard k*)
binaries = $(wildcard k*/*.exe.c)
functions = $(wildcard k*/*.fn.c) 
assemblies = $(wildcard k*/*.fn.$(TARGET).s)
binmods = $(sort $(dir $(binaries)))

................................................................................
uninstall: $(header-dir)/k $(lib-dir)/k
	rm -rf $^

lists = moddirs functions assemblies fnobjects rtobjects binaries binmods POSIX
dbg:
	@echo -e lists: $(foreach var, $(lists), "\\n - \\e[1m$(var)\\e[m = $($(var))")

%.obj: %/makefile $(TMP)/calls.h $(TMP)/calls.s $(OUT)
	cd $* && $(MAKE) obj

%.tool: %/makefile $(OUT)
	cd $* && $(MAKE) tool

%.dbg: %/makefile $(OUT)
	cd $* && $(MAKE) dbg

%.def: %/makefile $(TMP)/typesize.def $(OUT) $(OUT)/k
	cd $* && $(MAKE) def

.PRECIOUS: $(TMP)/calls.%
$(TMP)/calls.%: arch/makefile
	$(MAKE) -C arch $@

$(TMP)/typesize.def: arch/makefile $(TMP)
	$(MAKE) -C arch $@

$(OUT)/libk.so: $(fnobjects) 
	ld -shared $(COMPLIB) -o $@ $^







<
<







 







|











|
|







10
11
12
13
14
15
16


17
18
19
20
21
22
23
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
ifneq ($(BITS),)
    export TARGET = $(ARCH).$(OS).$(BITS)
else
    export TARGET = $(ARCH).$(OS)
endif

export m4 = m4



moddirs = $(wildcard k*)
binaries = $(wildcard k*/*.exe.c)
functions = $(wildcard k*/*.fn.c) 
assemblies = $(wildcard k*/*.fn.$(TARGET).s)
binmods = $(sort $(dir $(binaries)))

................................................................................
uninstall: $(header-dir)/k $(lib-dir)/k
	rm -rf $^

lists = moddirs functions assemblies fnobjects rtobjects binaries binmods POSIX
dbg:
	@echo -e lists: $(foreach var, $(lists), "\\n - \\e[1m$(var)\\e[m = $($(var))")

%.obj: %/makefile $(TMP)/system_calls.h $(TMP)/system_calls.s $(OUT)
	cd $* && $(MAKE) obj

%.tool: %/makefile $(OUT)
	cd $* && $(MAKE) tool

%.dbg: %/makefile $(OUT)
	cd $* && $(MAKE) dbg

%.def: %/makefile $(TMP)/typesize.def $(OUT) $(OUT)/k
	cd $* && $(MAKE) def

.PRECIOUS: $(TMP)/system_calls.%
$(TMP)/system_calls.%: arch/makefile
	$(MAKE) -C arch $@

$(TMP)/typesize.def: arch/makefile $(TMP)
	$(MAKE) -C arch $@

$(OUT)/libk.so: $(fnobjects) 
	ld -shared $(COMPLIB) -o $@ $^

Modified modmake from [5ed7cc8a39] to [0390aebc43].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
headers = $(wildcard *.h) $(gen-headers) $(patsubst %.m,%,$(wildcard *.h.m))

tools    = $(filter     %.exe.c,   $(src))
nontools = $(filter-out %.exe.c,   $(src))
cobjects = $(filter     %.c,       $(nontools))
sobjects = $(filter %.${TARGET}.s, $(nontools))

cflags = -std=c11 -isystem ${OUT} -isystem ${ROOT}/arch -fPIC -nostdlib ${COMPLIB} -L${OUT}

m-env = atom_target_arch=${ARCH}
m-env += atom_target_os=${OS}
ifneq (${BITS},) #!!! ifdef does NOT work with environment variables
    m-env += atom_target_bits=${BITS}
endif
m-env += target_posix=${POSIX}







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
headers = $(wildcard *.h) $(gen-headers) $(patsubst %.m,%,$(wildcard *.h.m))

tools    = $(filter     %.exe.c,   $(src))
nontools = $(filter-out %.exe.c,   $(src))
cobjects = $(filter     %.c,       $(nontools))
sobjects = $(filter %.${TARGET}.s, $(nontools))

cflags = -std=c11 -isystem ${OUT} -isystem ${TMP} -isystem ${ROOT}/arch -fPIC -nostdlib ${COMPLIB} -L${OUT}

m-env = atom_target_arch=${ARCH}
m-env += atom_target_os=${OS}
ifneq (${BITS},) #!!! ifdef does NOT work with environment variables
    m-env += atom_target_bits=${BITS}
endif
m-env += target_posix=${POSIX}