Hello and Hey,
Steffen Nurpmeso wrote in
<20200604235757.jxtge%[email protected]>:
|Steffen Nurpmeso wrote in
|<20200603135346.rbmv5%[email protected]>:
||Roberto Ricci wrote in
||<20200603132131.GA19797@ricci>:
|||I'm trying to cross-compile s-nail version 14.9.19 on a Void Linux host.
|||
|||I run the command:
||| make CC=name_of_cross_compiler OPT_CROSS_BUILD=yes config
|||but I get the following error:
||| [...]
||| . OS error mapping table generated ... no
||| make: *** [makefile:23: config] Error 1
|||
|||This probably happens because the config script needs to compile \
|||a program
|||and then run it. Obviously it fails if I am cross-compiling.
| ...
||What a mess ;-))
| ...
||moment, i think i will have to create something that uses the
||preprocessor to dump out data, and then a portable (awk?) parser
||has to parse that. Alternatively we need to add support for an
| ...
|
|So i have done exactly this, and it seems to work just fine.
|I hope CROSS_BUILD now works. Sorry for that inconvenience!
|I have pushed it to [master] and the [stable/] series.
I forgot to add the patch directly, sorry.
Please find it attached.
Ciao, and a nice Weekend everybody,
--steffen
|
|Der Kragenbaer, The moon bear,
|der holt sich munter he cheerfully and one by one
|einen nach dem anderen runter wa.ks himself off
|(By Robert Gernhardt)
diff --git a/mk/make-config.sh b/mk/make-config.sh
index ffe1614a..b281877d 100644
--- a/mk/make-config.sh
+++ b/mk/make-config.sh
@@ -1631,13 +1631,14 @@ fi
printf '#define su_PAGE_SIZE %su\n' "${i}" >> ${h}
# Generate SU <> OS error number mappings
-dump_test_program=0
-(
- feat_yes DEVEL && NV= || NV=noverbose
- SRCDIR="${SRCDIR}" TARGET="${h}" awk="${awk}" \
- ${SHELL} "${TOPDIR}"mk/su-make-errors.sh ${NV} config
-) | xrun_check oserrno 'OS error mapping table generated' || config_exit 1
-dump_test_program=1
+msg_nonl ' . OS error mapping table generated ... '
+feat_yes DEVEL && NV= || NV=noverbose
+SRCDIR="${SRCDIR}" TARGET="${h}" awk="${awk}" rm="${rm}" sort="${sort}" \
+ ${SHELL} "${TOPDIR}"mk/su-make-errors.sh ${NV} compile_time || {
+ msg 'no'
+ config_exit 1
+}
+msg 'yes'
## /SU
diff --git a/mk/su-make-errors.sh b/mk/su-make-errors.sh
index bc03944b..4ef84c4d 100644
--- a/mk/su-make-errors.sh
+++ b/mk/su-make-errors.sh
@@ -20,6 +20,9 @@ LC_ALL=C
export LC_ALL MAXDISTANCE_PENALTY VERB MAILX IN XOUT
: ${awk:=awk}
+# Compile-time only
+: ${rm:=rm}
+: ${sort:=sort}
# The set of errors we support
ERRORS="\
@@ -122,7 +125,7 @@ error_parse() {
d = substr(v, doff + 2, length(v) - doff - 1)
v = substr(v, 1, doff - 1)
}
- if(!incnone && v == "NONE")
+ if(!incnone && (v == "NONE" || v == "NOTOBACCO"))
continue
print dodoc ? d : v
}
@@ -130,162 +133,169 @@ error_parse() {
'
}
-config() {
+compile_time() {
[ -n "${TARGET}" ] || {
echo >&2 'Invalid usage'
exit 1
}
- # Note this may be ISO C89, so we cannot
- cat <<__EOT__
- #include <ctype.h>
- #include <errno.h>
- #include <limits.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #if defined __STDC_VERSION__ && __STDC_VERSION__ + 0 >= 199901L
- # include <stdint.h>
- #else
- # include <inttypes.h>
- #endif
- #include <${IN}>
- #ifdef UINT32_MAX
- typedef uint32_t u32;
- typedef int32_t s32;
- #elif ULONG_MAX == 0xFFFFFFFFu
- typedef unsigned long int u32;
- typedef signed long int s32;
- #else
- typedef unsigned int u32;
- typedef signed int s32;
- #endif
- struct a_in {struct a_in *next; char const *name; s32 no; u32 uno;};
- static int a_sortin(void const *a, void const *b){
- return (*(struct a_in const* const *)a)->uno -
- (*(struct a_in const* const *)b)->uno;
- }
- int main(void){
- struct a_in *head, *tail, *np, **nap;
- u32 maxsub, umax;
- s32 xavail = 0, total = 1, imin = 0, imax = 0, voidoff = 0, i, j;
- FILE *ofp = fopen("${TARGET}", "a");
- if(ofp == NULL){
- fprintf(stderr, "ERROR: cannot open output\n");
- return 1;
- }
- /* Create a list of all errors */
- head = tail = (struct a_in*)malloc(sizeof *head);
- head->next = NULL; head->name = "su_ERR_NONE"; head->no = 0;
-__EOT__
- for n in `error_parse 0 0`; do
- cat <<__EOT__
- ++total;
- #ifdef E${n}
- i = E${n};
- #else
- i = --xavail;
- #endif
- if(imin > i) {imin = i;} if(imax < i) {imax = i;}
- np = (struct a_in*)malloc(sizeof *np);
- np->next = NULL; np->name = "su_ERR_${n}"; np->no = i;
- tail->next = np; tail = np;
-__EOT__
- done
- cat <<__EOT__
- /* The unsigned type used for storage */
-
- fputs("#define su__ERR_NUMBER_TYPE ", ofp);
- if((u32)imax <= 0xFFu && (u32)-imin <= 0xFFu){
- fputs("u8\n", ofp);
- maxsub = 0xFFu;
- }else if(((u32)imax <= 0xFFFFu && (u32)-imin <= 0xFFFFu)){
- fputs("u16\n", ofp);
- maxsub = 0xFFFFu;
- }else{
- fputs("u32\n", ofp);
- maxsub = 0xFFFFFFFFu;
- }
+ {
+ printf '#include <errno.h>\nsu_ERROR_START\n'
+ for n in `error_parse 0 0`; do
+ printf '#ifdef E%s\nE%s %s\n#else\n-1 %s\n#endif\n' $n $n $n $n
+ done
+ } > "${TARGET}".c
+
+ # The problem is that at least (some versions of) gcc mangle output.
+ # Ensure we get both arguments on one line.
+ # While here sort numerically.
+ "${CC}" -E "${TARGET}".c |
+ ${awk} '
+ BEGIN{hot=0; conti=0}
+ /^[ ]*$/{next}
+ /^[ ]*#/{next}
+ /^su_ERROR_START$/{hot=1; next}
+ {
+ if(!hot)
+ next
+ printf "%s ", $1
+ if(conti){
+ printf "\n"
+ conti = 0
+ }else if($2 != "")
+ printf $2 "\n"
+ else
+ conti = 1
+ }
+ ' |
+ ${sort} -n > "${TARGET}".txt
- /* Now that we know the storage type, create the unsigned numbers */
- for(umax = 0, np = head; np != NULL; np = np->next){
- if(np->no < 0)
- np->uno = maxsub + np->no + 1;
- else
- np->uno = np->no;
- if(np->uno > umax)
- umax = np->uno;
- }
- if(umax <= (u32)imax){
- fprintf(stderr, "ERROR: errno ranges overlap\n");
- return 1;
- }
+ # EBCDIC/ASCII: we use \134 for \
+ j=\'
+ ${awk} -v verb="${VERB}" -v input="${ERRORS}" -v dat="${TARGET}.txt" '
+ BEGIN{
+ verb = verb ? " " : ""
- /* Sort this list */
+ # Read in our OS data
- nap = (struct a_in**)malloc(sizeof(*nap) * (unsigned)total);
- for(i = 0, np = head; np != NULL; ++i, np = np->next)
- nap[i] = np;
- if(i != total){
- fprintf(stderr, "ERROR: implementation error i != total\n");
- return 1;
- }
- qsort(nap, (u32)i, sizeof *nap, &a_sortin);
-
- /* The enumeration of numbers */
-
- fputs("#define su__ERR_NUMBER_ENUM_C \\\\\\n", ofp);
- for(i = 0; i < total; ++i)
- fprintf(ofp, " %s = %lu,\\\\\\n",
- nap[i]->name, (unsigned long)nap[i]->uno);
- fprintf(ofp, " su__ERR_NUMBER = %ld\\n", (long)total);
-
- fputs("#ifdef __cplusplus\n# define su__CXX_ERR_NUMBER_ENUM \\\\\\n",
- ofp);
- for(i = 0; i < total; ++i){
- char b[64], *cbp = b;
- char const *cp;
- cp = &nap[i]->name[sizeof("su_") -1];
- *cbp++ = 'e';
- for(cp += sizeof("ERR_") -1; *cp != '\0'; ++cp)
- *cbp++ = tolower(*cp);
- *cbp = '\0';
- fprintf(ofp, " %s = %s,\\\\\\n", b, nap[i]->name);
- }
- fprintf(ofp,
- " e__number = su__ERR_NUMBER\\n#endif /* __cplusplus */\n");
-
- /* The binary search mapping table from OS error value to our internal
- * a_corerr_map[] error description table */
- fprintf(ofp, "#define su__ERR_NUMBER_TO_MAPOFF \\\\\\n");
- for(xavail = 0, i = 0; i < total; ++i){
- if(i == 0 || nap[i]->no != nap[i - 1]->no){
- for(j = 0; a_names_alphasort[j] != NULL; ++j){
- if(!strcmp(&nap[i]->name[sizeof("su_ERR_") -1],
- a_names_alphasort[j]))
- break;
+ unavail = 0
+ max = 0
+ oscnt = 0
+ while(getline dl < dat){
+ split(dl, ia)
+
+ ++oscnt
+ osnoa[oscnt] = osonoa[oscnt] = ia[1]
+ osnaa[oscnt] = ia[2]
+
+ if(ia[1] < 0)
+ ++unavail
+ else{
+ if(ia[1] > max)
+ max = ia[1]
}
- fprintf(ofp, "\ta_X(%lu, %lu) %s%s%s\\\\\\n",
- (unsigned long)nap[i]->uno, (long)(u32)j,
- ((${VERB}) ? "/* " : ""), ((${VERB}) ? nap[i]->name : ""),
- ((${VERB}) ? " */ " : ""));
- if(!strcmp("su_ERR_NOTOBACCO", nap[i]->name))
- voidoff = j;
- ++xavail;
}
- }
- fprintf(ofp, "\\t/* %ld unique members */\\n", (long)xavail);
- fprintf(ofp, "#define su__ERR_NUMBER_VOIDOFF %ld\\n", (long)voidoff);
- fclose(ofp);
+ close(dat)
+
+ # Maximum error number defines the datatype to use.
+ # We need a value for NOTOBACCO, we warp all non-available errors to
+ # numbers too high to be regular errors, counting backwards
+
+ i = max + unavail + 1
+ if(i >= 65535){
+ t = "u32"
+ max = "0xFFFFFFFFu"
+ }else if(i >= 255){
+ t = "u16"
+ max = "0xFFFFu"
+ }else{
+ t = "u8"
+ max = "0xFFu"
+ }
+ print "#define su__ERR_NUMBER_TYPE " t
+ print "#define su__ERR_NUMBER_MAX " max
+
+ # Dump C table
+
+ unavail = 0
+ cnt = 0
+ print "#define su__ERR_NUMBER_ENUM_C \134"
+
+ print verb "su_ERR_NONE = 0,\134"
+ ++cnt
+
+ for(i = 1; i <= oscnt; ++i){
+ if(osnoa[i] < 0){
+ ++unavail
+ osnoa[i] = "(su__ERR_NUMBER_MAX - " unavail ")"
+ }
+ map[osnaa[i]] = osnoa[i]
+ print verb "su_ERR_" osnaa[i] " = " osnoa[i] ",\134"
+ ++cnt
+ }
+
+ print verb "su_ERR_NOTOBACCO = su__ERR_NUMBER_MAX,\134"
+ ++cnt
+
+ print verb "su__ERR_NUMBER = " cnt
+
+ # The C++ mapping table
+
+ print "#ifdef __cplusplus"
+ print "# define su__CXX_ERR_NUMBER_ENUM \134"
+ print verb "enone = su_ERR_NONE,\134"
+ for(i = 1; i <= oscnt; ++i)
+ print verb "e" tolower(osnaa[i]) " = su_ERR_" osnaa[i] ",\134"
+ print verb "enotobacco = su_ERR_NOTOBACCO,\134"
+ print verb "e__number = su__ERR_NUMBER"
+ print "#endif /* __cplusplus */"
+
+ # And our OS errno -> name map offset table
+
+ voidoff = 0
+ for(mapoff = 0;; ++mapoff){
+ voff = match(input, /[0-9a-zA-Z_]+(='${j}'[^'${j}']+)?/)
+ if(voff == 0)
+ break
+
+ v = substr(input, voff, RLENGTH)
+ input = substr(input, voff + RLENGTH)
+ doff = index(v, "=")
+ if(doff > 0){
+ d = substr(v, doff + 2, length(v) - doff - 1)
+ v = substr(v, 1, doff - 1)
+ }
+
+ mapo[v] = mapoff
+ if(v == "NOTOBACCO")
+ voidoff = mapoff
+ }
- while((np = head) != NULL){
- head = np->next;
- free(np);
+ uniq = 0
+ print "#define su__ERR_NUMBER_TO_MAPOFF \134"
+
+ print verb "a_X(0, 0) \134"
+ ++uniq
+
+ mapx[0] = 1
+ for(i = 1; i <= oscnt; ++i){
+ if(osonoa[i] < 0)
+ continue
+ if(mapx[osnoa[i]])
+ continue
+ mapx[osnoa[i]] = 1
+ ++uniq
+ print verb "a_X(" osnoa[i] ", " mapo[osnaa[i]] ") \134"
+ }
+
+ print verb "a_X(su__ERR_NUMBER_MAX, " voidoff ") \134"
+ ++uniq
+ print verb "/* " uniq " unique members */"
+ print "#define su__ERR_NUMBER_VOIDOFF " voidoff
}
- free(nap);
- return 0;
- }
-__EOT__
+ ' >> "${TARGET}"
+
+ ${rm} "${TARGET}".*
exit 0
}
@@ -298,7 +308,7 @@ if [ ${#} -ne 0 ]; then
fi
if [ ${#} -eq 1 ]; then
- [ "${1}" = config ] && config
+ [ "${1}" = compile_time ] && compile_time
elif [ ${#} -eq 0 ]; then
# Now start perl(1) without PERL5OPT set to avoid multibyte sequence errors
PERL5OPT= PERL5LIB= exec perl -x "${0}"
@@ -493,23 +503,6 @@ sub dump_map{
print F '/*@ ', scalar basen($ENV{XOUT}), ', generated by ',
scalar basen($0), ".\n *@ See core-errors.c for more */\n\n";
- print F '#ifndef su_SOURCE /* For compile-time tools only */', "\n",
- 'static char const * const a_names_alphasort[] = {';
- ($i, $alen) = (0, 0);
- foreach my $e (@ENTS){
- $i = 1 + 3 + length $e->{name};
- if($alen == 0 || $alen + $i > 75){
- print F "\n${S}";
- $alen = length $S
- }else{
- print F ' ';
- ++$i
- }
- $alen += $i;
- print F "\"$e->{name}\","
- }
- print F " NULL\n};\n#endif /* !su_SOURCE */\n\n";
-
($i, $alen) = (0, 0);
print F '#ifdef su_SOURCE', "\n",
'static char const a_corerr_names[] = {', "\n";