1 /* This file is part of bsconf - a configure replacement.
3 * Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
4 * This file is free software, distributed under the MIT License.
6 * bsconf was written to replace autoconf-made configure scripts, which
7 * through their prohibitively large size have fallen out of favor with
8 * many developers. The configure script performs many time-consuming
9 * tests, the results of which are usually unused because no progammer
10 * likes to pollute his code with ifdefs. This program performs the
11 * program and header lookup and substitutes @CONSTANTS@ in specified
12 * files. bsconf.h is used to define which files, programs, and headers
13 * to look for. config.h is generated, but the headers are only checked
14 * for existence and the functions are assumed to exist (nobody is going
15 * to ifdef around every memchr). Most compilers these days have all the
16 * headers you want, and if yours does not, there is always gcc. There
17 * is simply no excuse for using a braindead compiler when better ones
18 * are freely available.
25 #include <sys/types.h>
26 #include <sys/utsname.h>
29 /*- Types and macros -------------------------------------------------*/
31 #define VectorSize(v) (sizeof(v) / sizeof(*v))
32 #define foreachN(i,v,n) for (i = 0; i != VectorSize(v) / n; ++ i)
33 #define foreach(i,v) foreachN(i,v,1)
36 /*typedef unsigned int uint;*/
37 typedef char* pchar_t
;
38 typedef const char* cpchar_t
;
46 #define NULL_BUF { NULL, 0, 0, 0, 0 }
74 cpchar_t m_Description
;
79 cpchar_t m_Description
;
98 /*- Global variables -------------------------------------------------*/
101 #if !defined(BSCONF_VERSION) || BSCONF_VERSION < 0x03
102 #error Your bsconf.h file is too old; please update its format.
105 static cpchar_t g_ConfigV
[vv_last
] = {
128 static SBuf g_Subs
= NULL_BUF
;
129 static SBuf g_ConfigVV
[vv_last
], g_ProgLocs
[VectorSize (g_ProgVars
) / 4];
130 static SBuf g_CustomLibDirs
[16], g_CustomIncDirs
[16];
131 static int g_nCustomLibDirs
= 0, g_nCustomIncDirs
= 0;
132 static struct utsname g_Uname
;
133 static uint g_CpuCapBits
= 0;
134 static ESysType g_SysType
= sys_Unknown
;
136 static const SCpuCaps g_CpuCaps
[] = {
137 { 0, "FPU", "#undef CPU_HAS_FPU", "#define CPU_HAS_FPU 1" },
138 { 2, "DEBUG", "#undef CPU_HAS_EXT_DEBUG", "#define CPU_HAS_EXT_DEBUG 1" },
139 { 4, "TimeStamp", "#undef CPU_HAS_TIMESTAMPC", "#define CPU_HAS_TIMESTAMPC 1" },
140 { 5, "MSR", "#undef CPU_HAS_MSR", "#define CPU_HAS_MSR 1" },
141 { 8, "CMPXCHG8", "#undef CPU_HAS_CMPXCHG8", "#define CPU_HAS_CMPXCHG8 1" },
142 { 9, "APIC", "#undef CPU_HAS_APIC", "#define CPU_HAS_APIC 1" },
143 { 11, "SYSCALL", "#undef CPU_HAS_SYSCALL", "#define CPU_HAS_SYSCALL 1" },
144 { 12, "MTRR", "#undef CPU_HAS_MTRR", "#define CPU_HAS_MTRR 1" },
145 { 15, "CMOV", "#undef CPU_HAS_CMOV", "#define CPU_HAS_CMOV 1" },
146 { 16, "FCMOV", "#undef CPU_HAS_FCMOV", "#define CPU_HAS_FCMOV 1" },
147 { 22, "SSE", "#undef CPU_HAS_SSE ", "#define CPU_HAS_SSE 1" },
148 { 23, "MMX", "#undef CPU_HAS_MMX", "#define CPU_HAS_MMX 1" },
149 { 24, "FXSAVE", "#undef CPU_HAS_FXSAVE", "#define CPU_HAS_FXSAVE 1" },
150 { 25, "SSE", "#undef CPU_HAS_SSE ", "#define CPU_HAS_SSE 1" },
151 { 26, "SSE2", "#undef CPU_HAS_SSE2", "#define CPU_HAS_SSE2 1" },
152 { 30, "3dNow!+", "#undef CPU_HAS_EXT_3DNOW", "#define CPU_HAS_EXT_3DNOW 1" },
153 { 31, "3dNow!", "#undef CPU_HAS_3DNOW", "#define CPU_HAS_3DNOW 1" }
156 static const SHostType g_HostTypes
[] = {
157 { "linux", sys_Linux
},
159 { "solaris", sys_Sun
},
160 { "openbsd", sys_Bsd
},
161 { "netbsd", sys_Bsd
},
162 { "freebsd", sys_Bsd
},
164 { "darwin", sys_Mac
},
165 { "alpha", sys_Alpha
}
168 /*- Libc-like functions that might not exist -------------------------*/
170 static int StrLen (cpchar_t str
)
173 for (l
= 0; *str
; ++ l
, ++ str
);
177 static pchar_t
copy_n (cpchar_t src
, pchar_t dest
, int n
)
184 static void fill_n (pchar_t str
, int n
, char v
)
190 static void copy_backward (cpchar_t src
, pchar_t dest
, uint n
)
197 static void Lowercase (pchar_t str
)
200 if (*str
>= 'A' && *str
<= 'Z')
204 static int compare (cpchar_t str1
, cpchar_t str2
)
206 while (*str1
&& *str2
&& *str1
== *str2
)
211 static void FatalError (cpchar_t errortext
)
217 /*- Malloc buffer object ---------------------------------------------*/
219 static pchar_t
buf_addspace (pbuf_t p
, uint n
)
221 if ((p
->used
+= n
) > p
->allocated
) {
222 p
->allocated
= p
->used
;
223 if (!(p
->data
= (pchar_t
) realloc (p
->data
, p
->allocated
)))
224 FatalError ("out of memory");
226 return (p
->data
+ p
->used
- n
);
229 static void buf_clear (pbuf_t p
) { p
->used
= p
->last
; }
230 static void append (cpchar_t s
, pbuf_t p
) { copy_n (s
, buf_addspace (p
, StrLen(s
)), StrLen(s
)); }
231 static void copy (cpchar_t s
, pbuf_t p
) { buf_clear (p
); append (s
, p
); }
233 static void buf_copy_n (cpchar_t s
, pbuf_t p
, uint n
)
236 copy_n (s
, buf_addspace (p
, n
), n
);
239 static void append2 (cpchar_t s1
, cpchar_t s2
, pbuf_t p
)
241 uint l1
= StrLen(s1
), l2
= StrLen(s2
);
242 copy_n (s2
, copy_n (s1
, buf_addspace (p
, l1
+l2
), l1
), l2
);
245 static void buf_cap (pbuf_t p
)
247 if (p
->used
>= p
->allocated
|| p
->data
[p
->used
]) {
248 *buf_addspace(p
,1) = 0;
253 static pchar_t
buf_resize_fragment (pbuf_t p
, uint fo
, uint os
, uint ns
)
257 copy_n (p
->data
+ fo
- d
, p
->data
+ fo
, p
->used
- (fo
- d
));
261 copy_backward (p
->data
+ fo
, p
->data
+ fo
+ d
, p
->used
- (fo
+ d
));
264 return (p
->data
+ fo
);
267 static void pushstring (pbuf_t p
) { buf_cap (p
); p
->last
= p
->used
+ 1; }
268 static pchar_t
buf_str (pbuf_t p
) { buf_cap (p
); return (p
->data
+ p
->last
); }
269 #define S(buf) buf_str(&buf)
271 static void buf_free (pbuf_t p
)
276 p
->allocated
= p
->used
= p
->last
= 0;
279 /*- File I/O with buffer objects -------------------------------------*/
281 static void ReadFile (cpchar_t filename
, pbuf_t buf
)
284 FILE* fp
= fopen (filename
, "r");
287 if (fstat (fileno(fp
), &st
))
290 buf
->used
= fread (buf_addspace (buf
, st
.st_size
+ 1), 1, st
.st_size
, fp
);
291 if (((int) buf
->used
) < 0)
297 static void WriteFile (cpchar_t filename
, pbuf_t buf
)
300 FILE* fp
= fopen (filename
, "w");
303 bw
= fwrite (buf
->data
, 1, buf
->used
, fp
);
305 FatalError ("write");
307 FatalError ("close");
310 /*- Substitution engine ----------------------------------------------*/
312 static void MakeSubstString (cpchar_t str
, pbuf_t pbuf
)
315 append2 (str
, "@", pbuf
);
318 static void Substitute (cpchar_t matchStr
, cpchar_t replaceStr
)
320 copy (matchStr
, &g_Subs
);
321 pushstring (&g_Subs
);
322 copy (replaceStr
, &g_Subs
);
323 pushstring (&g_Subs
);
326 static void ExecuteSubstitutionList (pbuf_t buf
)
329 cpchar_t m
= g_Subs
.data
, r
;
330 pchar_t cp
, fbfirst
= S(*buf
);
332 while (m
< g_Subs
.data
+ g_Subs
.used
) {
336 for (cp
= fbfirst
; cp
< fbfirst
+ buf
->used
; ++ cp
) {
337 if (!compare (cp
, m
))
339 cp
= buf_resize_fragment (buf
, cp
- fbfirst
, ml
, rl
);
341 cp
= copy_n (r
, cp
, rl
);
347 static void ApplySubstitutions (void)
350 SBuf srcFile
= NULL_BUF
, fileBuf
= NULL_BUF
;
351 foreach (f
, g_Files
) {
352 copy (g_Files
[f
], &srcFile
);
353 append (".in", &srcFile
);
354 ReadFile (S(srcFile
), &fileBuf
);
355 ExecuteSubstitutionList (&fileBuf
);
356 WriteFile (g_Files
[f
], &fileBuf
);
362 /*- Housekeeping -----------------------------------------------------*/
364 static void InitGlobals (void)
367 SBuf nullBuf
= NULL_BUF
;
369 foreach (i
, g_ConfigVV
)
370 g_ConfigVV
[i
] = nullBuf
;
371 foreach (i
, g_CustomLibDirs
)
372 g_CustomLibDirs
[i
] = nullBuf
;
373 foreach (i
, g_CustomIncDirs
)
374 g_CustomIncDirs
[i
] = nullBuf
;
375 foreach (i
, g_ProgLocs
)
376 g_ProgLocs
[i
] = nullBuf
;
379 static void FreeGlobals (void)
383 foreach (i
, g_ConfigVV
)
384 buf_free (&g_ConfigVV
[i
]);
385 foreach (i
, g_CustomLibDirs
)
386 buf_free (&g_CustomLibDirs
[i
]);
387 foreach (i
, g_CustomIncDirs
)
388 buf_free (&g_CustomIncDirs
[i
]);
389 foreach (i
, g_ProgLocs
)
390 buf_free (&g_ProgLocs
[i
]);
393 static void PrintHelp (void)
397 "This program configures " PACKAGE_STRING
" to adapt to many kinds of systems.\n"
399 "Usage: configure [OPTION] ...\n"
402 " --help\t\tdisplay this help and exit\n"
403 " --version\t\tdisplay version information and exit\n"
405 "Installation directories:\n"
406 " --prefix=PREFIX\tarchitecture-independent files [/usr/local]\n"
407 " --exec-prefix=EPREFIX\tarchitecture-dependent files [PREFIX]\n"
408 " --bindir=DIR\t\tuser executables [EPREFIX/bin]\n"
409 " --sbindir=DIR\t\tsystem admin executables [EPREFIX/sbin]\n"
410 " --libexecdir=DIR\tprogram executables [EPREFIX/libexec]\n"
411 " --datadir=DIR\t\tread-only architecture-independent data [PREFIX/share]\n"
412 " --sysconfdir=DIR\tread-only single-machine data [PREFIX/etc]\n"
413 " --sharedstatedir=DIR\tmodifiable architecture-independent data [PREFIX/com]\n"
414 " --localstatedir=DIR\tmodifiable single-machine data [PREFIX/var]\n"
415 " --libdir=DIR\t\tobject code libraries [EPREFIX/lib]\n"
416 " --includedir=DIR\tC header files [PREFIX/include]\n"
417 " --oldincludedir=DIR\tC header files for non-gcc [/usr/include]\n"
418 " --gccincludedir=DIR\tGCC internal header files [PREFIX/include]\n"
419 " --custominclude=DIR\tNonstandard header file location (cumulative)\n"
420 " --customlib=DIR\tNonstandard library file location (cumulative)\n"
421 " --infodir=DIR\t\tinfo documentation [PREFIX/info]\n"
422 " --mandir=DIR\t\tman documentation [PREFIX/man]\n"
425 " --build=BUILD\t\tconfigure for building on BUILD [guessed]\n"
426 " --host=HOST\t\tcross-compile to build programs to run on HOST [BUILD]\n"
428 if (VectorSize(g_Components
)) {
429 printf ("Options:\n");
430 foreach (i
, g_ComponentInfos
) {
431 if (!g_ComponentInfos
[i
].m_Description
[0])
433 if (g_ComponentInfos
[i
].m_bDefaultOn
)
434 printf (" --without-%-12s%s\n", g_Components
[i
* 3], g_ComponentInfos
[i
].m_Description
);
436 printf (" --with-%-15s%s\n", g_Components
[i
* 3], g_ComponentInfos
[i
].m_Description
);
441 "Some influential environment variables:\n"
442 " CC\t\tC compiler\t\tCFLAGS\n"
443 " CPP\t\tC preprocessor\t\tCPPFLAGS\n"
444 " CXX\t\tC++ compiler\t\tCXXFLAGS\n"
445 " LD\t\tLinker\t\t\tLDFLAGS\n"
447 "Report bugs to " PACKAGE_BUGREPORT
".\n");
451 static void PrintVersion (void)
453 printf (PACKAGE_NAME
" configure " PACKAGE_VERSION
"\n"
454 "\nUsing bsconf package version 0.3\n"
455 "Copyright (c) 2003-2005, Mike Sharov <msharov@users.sourceforge.net>\n"
456 "This configure script and the bsconf package are free software.\n"
457 "Unlimited permission to copy, distribute, and modify is granted.\n");
461 /*- Configuration routines -------------------------------------------*/
463 static void GetConfigVarValues (int argc
, cpchar_t
const* argv
)
468 for (a
= 0; a
< argc
; ++ a
) {
469 if (!compare (argv
[a
], "--"))
472 if (compare (argv
[a
] + apos
, "help"))
474 else if (compare (argv
[a
] + apos
, "version"))
476 else if (compare (argv
[a
] + apos
, "with")) {
478 if (compare (argv
[a
] + apos
, "out"))
481 foreach (cv
, g_ComponentInfos
)
482 if (compare (argv
[a
] + apos
, g_Components
[cv
* 3]))
483 g_ComponentInfos
[cv
].m_bDefaultOn
= (apos
== 7);
485 foreach (cv
, g_ConfigV
)
486 if (compare (argv
[a
] + apos
, g_ConfigV
[cv
]))
490 apos
+= StrLen (g_ConfigV
[cv
]) + 1;
491 cvl
= StrLen (argv
[a
]) - apos
+ 1;
493 buf_copy_n (argv
[a
] + apos
, &g_ConfigVV
[cv
], cvl
);
494 if (cv
== vv_customlib
)
495 buf_copy_n (argv
[a
] + apos
, &g_CustomLibDirs
[g_nCustomLibDirs
++], cvl
);
496 else if (cv
== vv_custominclude
)
497 buf_copy_n (argv
[a
] + apos
, &g_CustomIncDirs
[g_nCustomIncDirs
++], cvl
);
499 if (cv
== vv_prefix
&& compare (S(g_ConfigVV
[cv
]), "/home")) {
500 copy (S(g_ConfigVV
[cv
]), &g_CustomLibDirs
[g_nCustomLibDirs
]);
501 append ("/lib", &g_CustomLibDirs
[g_nCustomLibDirs
++]);
502 copy (S(g_ConfigVV
[cv
]), &g_CustomIncDirs
[g_nCustomIncDirs
]);
503 append ("/include", &g_CustomIncDirs
[g_nCustomIncDirs
++]);
509 static void DefaultConfigVarValue (EVV v
, EVV root
, cpchar_t suffix
)
511 if (!*S(g_ConfigVV
[v
])) {
512 copy (S(g_ConfigVV
[root
]), &g_ConfigVV
[v
]);
513 append (suffix
, &g_ConfigVV
[v
]);
517 static void DetermineHost (void)
520 fill_n ((pchar_t
) &g_Uname
, sizeof(struct utsname
), 0);
522 Lowercase (g_Uname
.machine
);
523 Lowercase (g_Uname
.sysname
);
524 copy (g_Uname
.machine
, &g_ConfigVV
[vv_host
]);
525 append ("-", &g_ConfigVV
[vv_host
]);
527 append ("gnu", &g_ConfigVV
[vv_host
]);
529 append ("unknown", &g_ConfigVV
[vv_host
]);
531 append2 ("-", g_Uname
.sysname
, &g_ConfigVV
[vv_host
]);
532 foreach (i
, g_HostTypes
)
533 if (compare (g_Uname
.sysname
, g_HostTypes
[i
].sysname
))
534 g_SysType
= g_HostTypes
[i
].type
;
535 if (compare (g_Uname
.machine
, "alpha"))
536 g_SysType
= sys_Alpha
;
539 static void FillInDefaultConfigVarValues (void)
541 typedef struct _SDefaultPathMap
{
546 static const SDefaultPathMap c_Defaults
[] = {
547 { vv_bindir
, vv_exec_prefix
, "/bin" },
548 { vv_sbindir
, vv_exec_prefix
, "/sbin" },
549 { vv_libexecdir
, vv_prefix
, "/libexec" },
550 { vv_datadir
, vv_prefix
, "/share" },
551 { vv_sysconfdir
, vv_prefix
, "/etc" },
552 { vv_sharedstatedir
, vv_prefix
, "/com" },
553 { vv_localstatedir
, vv_prefix
, "/var" },
554 { vv_libdir
, vv_exec_prefix
, "/lib" },
555 { vv_gcclibdir
, vv_exec_prefix
, "/lib" },
556 { vv_includedir
, vv_prefix
, "/include" },
557 { vv_gccincludedir
, vv_prefix
, "/include" },
558 { vv_infodir
, vv_prefix
, "/info" },
559 { vv_mandir
, vv_prefix
, "/man" }
563 if (!*S(g_ConfigVV
[vv_prefix
]))
564 copy ("/usr/local", &g_ConfigVV
[vv_prefix
]);
565 else if (S(g_ConfigVV
[vv_prefix
])[0] == '/' && !S(g_ConfigVV
[vv_prefix
])[1])
566 g_ConfigVV
[vv_prefix
].data
[0] = 0;
567 if (!*S(g_ConfigVV
[vv_exec_prefix
]))
568 DefaultConfigVarValue (vv_exec_prefix
, vv_prefix
, "");
569 else if (S(g_ConfigVV
[vv_exec_prefix
])[0] == '/' && !S(g_ConfigVV
[vv_exec_prefix
])[1])
570 g_ConfigVV
[vv_exec_prefix
].data
[0] = 0;
571 if (!*S(g_ConfigVV
[vv_oldincludedir
]))
572 copy ("/usr/include", &g_ConfigVV
[vv_oldincludedir
]);
574 foreach (i
, c_Defaults
)
575 DefaultConfigVarValue (c_Defaults
[i
].var
, c_Defaults
[i
].base
, c_Defaults
[i
].path
);
577 if (!*S(g_ConfigVV
[vv_prefix
]))
578 copy ("/usr", &g_ConfigVV
[vv_prefix
]);
579 if (!*S(g_ConfigVV
[vv_exec_prefix
]))
580 copy ("/usr", &g_ConfigVV
[vv_exec_prefix
]);
582 if (!*S(g_ConfigVV
[vv_host
]))
584 if (!*S(g_ConfigVV
[vv_build
]))
585 copy (S(g_ConfigVV
[vv_host
]), &g_ConfigVV
[vv_build
]);
588 static cpchar_t
CopyPathEntry (cpchar_t pi
, pbuf_t dest
)
591 while (pi
[pil
] && pi
[pil
] != ':') ++ pil
;
592 buf_copy_n (pi
, dest
, pil
);
593 return (*(pi
+= pil
) ? ++pi
: NULL
);
596 static int IsBadInstallDir (cpchar_t match
)
598 static const char* c_BadDirs
[] = {
599 "/etc", "/usr/sbin", "/c", "/C", "/usr/etc",
600 "/sbin", "/usr/ucb", "/usr/afsws/bin"
603 foreach (i
, c_BadDirs
)
604 if (compare (match
, c_BadDirs
[i
]))
609 static void FindPrograms (void)
613 SBuf match
= NULL_BUF
;
615 path
= getenv ("PATH");
619 foreach (i
, g_ProgLocs
) {
622 for (pi
= path
; pi
; pi
= CopyPathEntry (pi
, &match
)) {
623 /* Ignore "bad" versions of install, like autoconf does. */
624 if (compare (g_ProgVars
[i
* 4 + 1], "install") && IsBadInstallDir (S(match
)))
626 append2 ("/", g_ProgVars
[i
* 4 + 1], &match
);
627 if (access (S(match
), X_OK
) == 0) {
632 if (count
&& compare (g_ProgVars
[i
* 4 + 1], "install"))
633 copy (S(match
), &g_ProgLocs
[i
]);
635 copy (g_ProgVars
[i
* 4 + 2 + !count
], &g_ProgLocs
[i
]);
640 static void SubstitutePaths (void)
642 SBuf match
= NULL_BUF
;
644 foreach (cv
, g_ConfigV
) {
645 MakeSubstString (g_ConfigV
[cv
], &match
);
646 Substitute (S(match
), S(g_ConfigVV
[cv
]));
651 static void SubstituteCFlags (void)
656 for (j
= 0; j
< g_nCustomIncDirs
; ++ j
)
657 append2 (" -I", S(g_CustomIncDirs
[j
]), &buf
);
658 Substitute ("@CUSTOMINCDIR@", S(buf
));
661 for (j
= 0; j
< g_nCustomLibDirs
; ++ j
)
662 append2 (" -L", S(g_CustomLibDirs
[j
]), &buf
);
663 Substitute ("@CUSTOMLIBDIR@", S(buf
));
667 if (g_CpuCapBits
& (1 << 23))
668 append (" -mmmx", &buf
);
669 if (g_SysType
== sys_Linux
)
670 if (g_CpuCapBits
& ((1 << 22) | (1 << 25)))
671 append (" -msse -mfpmath=sse", &buf
);
672 if (g_CpuCapBits
& (1 << 26))
673 append (" -msse2", &buf
);
674 if (g_CpuCapBits
& ((1 << 30) | (1 << 31)))
675 append (" -m3dnow", &buf
);
677 Substitute ("@PROCESSOR_OPTS@", S(buf
));
680 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
681 copy (" --param max-inline-insns-single=1024", &buf
);
682 append (" \\\n\t\t--param large-function-growth=65535", &buf
);
683 append (" \\\n\t\t--param inline-unit-growth=1024", &buf
);
685 copy ("-finline-limit=65535", &buf
);
688 append (" \\\n\t\t-fvisibility-inlines-hidden", &buf
);
691 Substitute ("@INLINE_OPTS@", S(buf
));
694 Substitute ("-fPIC", "");
699 static void SubstituteEnvironment (int bForce
)
701 SBuf match
= NULL_BUF
;
705 foreach (i
, g_EnvVars
) {
706 envval
= getenv (g_EnvVars
[i
]);
712 MakeSubstString (g_EnvVars
[i
], &match
);
713 Substitute (S(match
), envval
);
718 static void SubstitutePrograms (void)
721 SBuf match
= NULL_BUF
;
722 foreach (i
, g_ProgLocs
) {
723 MakeSubstString (g_ProgVars
[i
* 4], &match
);
724 Substitute (S(match
), S(g_ProgLocs
[i
]));
729 #if defined(__GNUC__) && (__i386__ || __x86_64)
730 static uint
cpuid_supported (void)
732 unsigned long forig
, fnew
;
733 /* Pop flags, toggle ID bit, push, pop. cpuid supported if changed. */
734 asm ("pushf\n\tpop\t%0\n\t"
735 "mov\t%0, %1\n\txor\t$0x200000, %0\n\t"
736 "push\t%0\n\tpopf\n\tpushf\n\tpop\t%0"
737 : "=r"(fnew
), "=r"(forig
));
738 return (fnew
!= forig
);
741 static uint
cpuid (void)
743 #define i_cpuid(a,r,c,d) asm("cpuid":"=a"(r),"=c"(c),"=d"(d):"0"(a):"%ebx")
744 const uint amdBits
= 0xC9480000, extFeatures
= 0x80000000, amdExtensions
= 0x80000001;
746 if (!cpuid_supported()) return (0);
747 i_cpuid (0, r
, c
, d
);
749 i_cpuid (1, r
, c
, d
); /* Ask for feature list */
750 caps
= (d
& ~amdBits
);
751 i_cpuid (extFeatures
, r
, c
, d
);
752 if (r
!= extFeatures
) {
753 i_cpuid (amdExtensions
, r
, c
, d
);
759 static uint
cpuid (void) { return (0); }
762 static void SubstituteCpuCaps (void)
765 g_CpuCapBits
= cpuid();
766 foreach (i
, g_CpuCaps
)
767 if (g_CpuCapBits
& (1 << g_CpuCaps
[i
].m_Bit
))
768 Substitute (g_CpuCaps
[i
].m_Disabled
, g_CpuCaps
[i
].m_Enabled
);
771 static void SubstituteHostOptions (void)
773 static const short int boCheck
= 0x0001;
774 static const char boNames
[2][16] = { "BIG_ENDIAN", "LITTLE_ENDIAN" };
777 if (g_SysType
== sys_Sun
)
779 Substitute ("-Wredundant-decls", "-Wno-redundant-decls");
781 if (g_SysType
== sys_Bsd
) {
782 Substitute (" @libgcc_eh@", "");
783 Substitute ("#define WITHOUT_LIBSTDCPP 1", "#undef WITHOUT_LIBSTDCPP");
784 Substitute ("NOLIBSTDCPP\t= -nodefaultlibs ", "#NOLIBSTDCPP\t= -nodefaultlibs");
785 Substitute ("-Wredundant-decls", "-Wno-redundant-decls");
786 Substitute ("-Winline", "-Wno-inline");
789 if ((g_SysType
== sys_Linux
) | (g_SysType
== sys_Bsd
))
790 Substitute ("@SHBLDFL@", "-shared -Wl,-soname=${LIBSOLNK}");
791 else if (g_SysType
== sys_Mac
)
792 Substitute ("@SHBLDFL@", "-Wl,-single_module -compatibility_version 1 -current_version 1 -install_name ${LIBSOLNK} -Wl,-Y,1455 -dynamiclib -mmacosx-version-min=10.4");
793 else if (g_SysType
== sys_Sun
)
794 Substitute ("@SHBLDFL@", "-G");
796 Substitute ("BUILD_SHARED\t= 1 ", "#BUILD_SHARED\t= 1");
797 Substitute ("#BUILD_STATIC\t= 1", "BUILD_STATIC\t= 1 ");
800 if (g_SysType
== sys_Mac
) {
801 Substitute (" @libgcc_eh@", "");
802 Substitute ("@libgcc@", "@libsupc++@ @libgcc@");
803 Substitute ("@SYSWARNS@", "-Wno-long-double");
804 Substitute ("lib${LIBNAME}.so", "lib${LIBNAME}.dylib");
805 Substitute ("${LIBSO}.${MAJOR}.${MINOR}.${BUILD}", "lib${LIBNAME}.${MAJOR}.${MINOR}.${BUILD}.dylib");
806 Substitute ("${LIBSO}.${MAJOR}.${MINOR}", "lib${LIBNAME}.${MAJOR}.${MINOR}.dylib");
807 Substitute ("${LIBSO}.${MAJOR}", "lib${LIBNAME}.${MAJOR}.dylib");
809 Substitute ("@SYSWARNS@", "");
811 if (g_SysType
!= sys_Sun
)
812 Substitute ("#undef HAVE_THREE_CHAR_TYPES", "#define HAVE_THREE_CHAR_TYPES 1");
814 Substitute ("#undef RETSIGTYPE", "#define RETSIGTYPE void");
815 Substitute ("#undef const", "/* #define const */");
816 Substitute ("#undef inline", "/* #define inline __inline */");
817 Substitute ("#undef off_t", "/* typedef long off_t; */");
818 Substitute ("#undef size_t", "/* typedef long size_t; */");
820 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_CHAR %d", sizeof(char));
821 Substitute ("#undef SIZE_OF_CHAR", buf
);
822 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_SHORT %d", sizeof(short));
823 Substitute ("#undef SIZE_OF_SHORT", buf
);
824 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_INT %d", sizeof(int));
825 Substitute ("#undef SIZE_OF_INT", buf
);
826 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_LONG %d", sizeof(long));
827 Substitute ("#undef SIZE_OF_LONG ", buf
);
828 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_POINTER %d", sizeof(void*));
829 Substitute ("#undef SIZE_OF_POINTER ", buf
);
830 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_SIZE_T %d", sizeof(size_t));
831 Substitute ("#undef SIZE_OF_SIZE_T ", buf
);
832 if (g_SysType
== sys_Alpha
|| g_SysType
== sys_Mac
)
833 Substitute ("#undef SIZE_OF_BOOL ", "#define SIZE_OF_BOOL SIZE_OF_LONG");
835 Substitute ("#undef SIZE_OF_BOOL ", "#define SIZE_OF_BOOL SIZE_OF_CHAR");
836 if ((sizeof(size_t) == sizeof(unsigned long) &&
837 sizeof(size_t) != sizeof(uint
)) || g_SysType
== sys_Mac
)
838 Substitute ("#undef SIZE_T_IS_LONG", "#define SIZE_T_IS_LONG 1");
839 #if defined(__GNUC__) || (__WORDSIZE == 64) || defined(__ia64__)
840 if (g_SysType
!= sys_Bsd
)
841 Substitute ("#undef HAVE_INT64_T", "#define HAVE_INT64_T 1");
843 #if defined(__GNUC__) || defined(__GLIBC_HAVE_LONG_LONG)
844 Substitute ("#undef HAVE_LONG_LONG", "#define HAVE_LONG_LONG 1");
845 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_LONG_LONG %d", sizeof(long long));
846 Substitute ("#undef SIZE_OF_LONG_LONG", buf
);
848 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
849 Substitute ("#undef HAVE_VECTOR_EXTENSIONS", "#define HAVE_VECTOR_EXTENSIONS 1");
851 Substitute ("-Wshadow ", "");
854 Substitute ("#undef LSTAT_FOLLOWS_SLASHED_SYMLINK", "#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1");
855 Substitute ("#undef HAVE_STAT_EMPTY_STRING_BUG", "/* #undef HAVE_STAT_EMPTY_STRING_BUG */");
857 if (g_SysType
== sys_Linux
)
858 Substitute ("#undef HAVE_RINTF", "#define HAVE_RINTF 1");
860 Substitute ("@BYTE_ORDER@", boNames
[(uint
)(*((const char*)&boCheck
))]);
863 static void SubstituteCustomVars (void)
866 SBuf match
= NULL_BUF
;
867 foreachN (i
, g_CustomVars
, 2) {
868 MakeSubstString (g_CustomVars
[i
* 2], &match
);
869 Substitute (S(match
), g_CustomVars
[i
* 2 + 1]);
874 static void SubstituteHeaders (void)
878 SBuf defaultPath
= NULL_BUF
, match
= NULL_BUF
;
880 copy (S(g_ConfigVV
[vv_includedir
]), &defaultPath
);
881 append2 (":", S(g_ConfigVV
[vv_oldincludedir
]), &defaultPath
);
882 append2 (":", S(g_ConfigVV
[vv_gccincludedir
]), &defaultPath
);
883 for (i
= 0; i
!= (uint
) g_nCustomIncDirs
; ++ i
)
884 append2 (":", S(g_CustomIncDirs
[i
]), &defaultPath
);
885 foreachN (i
, g_Headers
, 3) {
886 for (pi
= S(defaultPath
); pi
; pi
= CopyPathEntry (pi
, &match
)) {
887 append2 ("/", g_Headers
[i
* 3], &match
);
888 if (access (S(match
), R_OK
) == 0)
889 Substitute (g_Headers
[i
* 3 + 1], g_Headers
[i
* 3 + 2]);
893 buf_free (&defaultPath
);
896 static void SubstituteLibs (void)
898 static const cpchar_t g_LibSuffixes
[] = { ".a", ".so", ".la", ".dylib" };
901 SBuf defaultPath
= NULL_BUF
, match
= NULL_BUF
;
903 copy ("/lib:/usr/lib:/usr/local/lib", &defaultPath
);
904 pi
= getenv ("LD_LIBRARY_PATH");
906 append2 (":", pi
, &defaultPath
);
907 append2 (":", S(g_ConfigVV
[vv_libdir
]), &defaultPath
);
908 append2 (":", S(g_ConfigVV
[vv_gcclibdir
]), &defaultPath
);
909 for (i
= 0; i
!= (uint
) g_nCustomLibDirs
; ++ i
)
910 append2 (":", S(g_CustomLibDirs
[i
]), &defaultPath
);
912 foreachN (i
, g_Libs
, 3) {
914 for (pi
= S(defaultPath
); pi
; pi
= CopyPathEntry (pi
, &match
)) {
915 foreach (k
, g_LibSuffixes
) {
916 CopyPathEntry (pi
, &match
);
917 append2 ("/lib", g_Libs
[i
* 3], &match
);
918 append (g_LibSuffixes
[k
], &match
);
919 if (access (S(match
), R_OK
) == 0)
923 copy ("@lib", &match
);
924 append2 (g_Libs
[i
* 3], "@", &match
);
925 Substitute (S(match
), g_Libs
[i
* 3 + 1 + ok
]);
928 buf_free (&defaultPath
);
931 static void SubstituteFunctions (void)
934 foreachN (i
, g_Functions
, 3)
935 Substitute (g_Functions
[i
* 3 + 1], g_Functions
[i
* 3 + 2]);
936 if ((g_SysType
== sys_Mac
) | (g_SysType
== sys_Bsd
))
937 Substitute ("#define HAVE_STRSIGNAL 1", "#undef HAVE_STRSIGNAL");
938 if (g_SysType
== sys_Bsd
)
939 Substitute ("#define HAVE_VA_COPY 1", "#undef HAVE_VA_COPY");
942 static void SubstituteComponents (void)
945 foreachN (i
, g_Components
, 3) {
946 isOn
= g_ComponentInfos
[i
].m_bDefaultOn
;
947 Substitute (g_Components
[i
* 3 + 1 + !isOn
], g_Components
[i
* 3 + 1 + isOn
]);
951 /*--------------------------------------------------------------------*/
953 int main (int argc
, const char* const* argv
)
956 GetConfigVarValues (--argc
, ++argv
);
957 FillInDefaultConfigVarValues();
960 SubstituteComponents();
961 SubstituteHostOptions();
965 SubstituteEnvironment (0);
966 SubstitutePrograms();
969 SubstituteFunctions();
970 SubstituteCustomVars();
971 SubstituteEnvironment (1);
973 ApplySubstitutions();