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 /*- The configuration header and its types ---------------------------*/
31 #define VectorSize(v) (sizeof(v) / sizeof(*v))
34 /*typedef unsigned int uint;*/
35 typedef char* pchar_t
;
36 typedef const char* cpchar_t
;
40 cpchar_t m_Description
;
44 #if !defined(BSCONF_VERSION) || BSCONF_VERSION < 0x03
45 #error Your bsconf.h file is too old; please update its format.
48 /*- Internal types and macros ----------------------------------------*/
50 #define foreachN(i,v,n) for (i = 0; i != VectorSize(v) / n; ++ i)
51 #define foreach(i,v) foreachN(i,v,1)
60 #define NULL_BUF { NULL, 0, 0, 0, 0 }
86 static char g_ConfigV
[vv_last
][16] = {
109 static SBuf g_Subs
= NULL_BUF
;
110 static SBuf g_ConfigVV
[vv_last
], g_ProgLocs
[VectorSize (g_ProgVars
) / 4];
111 static SBuf g_CustomLibDirs
[16], g_CustomIncDirs
[16];
112 static int g_nCustomLibDirs
= 0, g_nCustomIncDirs
= 0;
113 static struct utsname g_Uname
;
114 static uint g_CpuCapBits
= 0;
125 static ESysType g_SysType
= sys_Unknown
;
127 /*- Libc-like functions that might not exist -------------------------*/
129 static int StrLen (cpchar_t str
)
132 for (l
= 0; *str
; ++ l
, ++ str
);
136 static pchar_t
copy_n (cpchar_t src
, pchar_t dest
, int n
)
143 static void fill_n (pchar_t str
, int n
, char v
)
149 static void copy_backward (cpchar_t src
, pchar_t dest
, uint n
)
156 static void Lowercase (pchar_t str
)
159 if (*str
>= 'A' && *str
<= 'Z')
163 static int compare (cpchar_t str1
, cpchar_t str2
)
165 while (*str1
&& *str2
&& *str1
== *str2
)
170 static void FatalError (cpchar_t errortext
)
176 /*- Malloc buffer object ---------------------------------------------*/
178 static pchar_t
buf_addspace (pbuf_t p
, uint n
)
180 if ((p
->used
+= n
) > p
->allocated
) {
181 p
->allocated
= p
->used
;
182 if (!(p
->data
= (pchar_t
) realloc (p
->data
, p
->allocated
)))
183 FatalError ("out of memory");
185 return (p
->data
+ p
->used
- n
);
188 static void buf_clear (pbuf_t p
) { p
->used
= p
->last
; }
189 static void append (cpchar_t s
, pbuf_t p
) { copy_n (s
, buf_addspace (p
, StrLen(s
)), StrLen(s
)); }
190 static void copy (cpchar_t s
, pbuf_t p
) { buf_clear (p
); append (s
, p
); }
192 static void buf_copy_n (cpchar_t s
, pbuf_t p
, uint n
)
195 copy_n (s
, buf_addspace (p
, n
), n
);
198 static void append2 (cpchar_t s1
, cpchar_t s2
, pbuf_t p
)
200 uint l1
= StrLen(s1
), l2
= StrLen(s2
);
201 copy_n (s2
, copy_n (s1
, buf_addspace (p
, l1
+l2
), l1
), l2
);
204 static void buf_cap (pbuf_t p
)
206 if (p
->used
>= p
->allocated
|| p
->data
[p
->used
]) {
207 *buf_addspace(p
,1) = 0;
212 static pchar_t
buf_resize_fragment (pbuf_t p
, uint fo
, uint os
, uint ns
)
216 copy_n (p
->data
+ fo
- d
, p
->data
+ fo
, p
->used
- (fo
- d
));
220 copy_backward (p
->data
+ fo
, p
->data
+ fo
+ d
, p
->used
- (fo
+ d
));
223 return (p
->data
+ fo
);
226 static void pushstring (pbuf_t p
) { buf_cap (p
); p
->last
= p
->used
+ 1; }
227 static pchar_t
buf_str (pbuf_t p
) { buf_cap (p
); return (p
->data
+ p
->last
); }
228 #define S(buf) buf_str(&buf)
230 static void buf_free (pbuf_t p
)
235 p
->allocated
= p
->used
= p
->last
= 0;
238 /*- File I/O with buffer objects -------------------------------------*/
240 static void ReadFile (cpchar_t filename
, pbuf_t buf
)
243 FILE* fp
= fopen (filename
, "r");
246 if (fstat (fileno(fp
), &st
))
249 buf
->used
= fread (buf_addspace (buf
, st
.st_size
+ 1), 1, st
.st_size
, fp
);
250 if (((int) buf
->used
) < 0)
256 static void WriteFile (cpchar_t filename
, pbuf_t buf
)
259 FILE* fp
= fopen (filename
, "w");
262 bw
= fwrite (buf
->data
, 1, buf
->used
, fp
);
264 FatalError ("write");
266 FatalError ("close");
269 /*- Substitution engine ----------------------------------------------*/
271 static void MakeSubstString (cpchar_t str
, pbuf_t pbuf
)
274 append2 (str
, "@", pbuf
);
277 static void Substitute (cpchar_t matchStr
, cpchar_t replaceStr
)
279 copy (matchStr
, &g_Subs
);
280 pushstring (&g_Subs
);
281 copy (replaceStr
, &g_Subs
);
282 pushstring (&g_Subs
);
285 static void ExecuteSubstitutionList (pbuf_t buf
)
288 cpchar_t m
= g_Subs
.data
, r
;
289 pchar_t cp
, fbfirst
= S(*buf
);
291 while (m
< g_Subs
.data
+ g_Subs
.used
) {
295 for (cp
= fbfirst
; cp
< fbfirst
+ buf
->used
; ++ cp
) {
296 if (!compare (cp
, m
))
298 cp
= buf_resize_fragment (buf
, cp
- fbfirst
, ml
, rl
);
300 cp
= copy_n (r
, cp
, rl
);
306 static void ApplySubstitutions (void)
309 SBuf srcFile
= NULL_BUF
, fileBuf
= NULL_BUF
;
310 foreach (f
, g_Files
) {
311 copy (g_Files
[f
], &srcFile
);
312 append (".in", &srcFile
);
313 ReadFile (S(srcFile
), &fileBuf
);
314 ExecuteSubstitutionList (&fileBuf
);
315 WriteFile (g_Files
[f
], &fileBuf
);
321 /*- Housekeeping -----------------------------------------------------*/
323 static void InitGlobals (void)
326 SBuf nullBuf
= NULL_BUF
;
328 foreach (i
, g_ConfigVV
)
329 g_ConfigVV
[i
] = nullBuf
;
330 foreach (i
, g_CustomLibDirs
)
331 g_CustomLibDirs
[i
] = nullBuf
;
332 foreach (i
, g_CustomIncDirs
)
333 g_CustomIncDirs
[i
] = nullBuf
;
334 foreach (i
, g_ProgLocs
)
335 g_ProgLocs
[i
] = nullBuf
;
338 static void FreeGlobals (void)
342 foreach (i
, g_ConfigVV
)
343 buf_free (&g_ConfigVV
[i
]);
344 foreach (i
, g_CustomLibDirs
)
345 buf_free (&g_CustomLibDirs
[i
]);
346 foreach (i
, g_CustomIncDirs
)
347 buf_free (&g_CustomIncDirs
[i
]);
348 foreach (i
, g_ProgLocs
)
349 buf_free (&g_ProgLocs
[i
]);
352 static void PrintHelp (void)
356 "This program configures " PACKAGE_STRING
" to adapt to many kinds of systems.\n"
358 "Usage: configure [OPTION] ...\n"
361 " --help\t\tdisplay this help and exit\n"
362 " --version\t\tdisplay version information and exit\n"
364 "Installation directories:\n"
365 " --prefix=PREFIX\tarchitecture-independent files [/usr/local]\n"
366 " --exec-prefix=EPREFIX\tarchitecture-dependent files [PREFIX]\n"
367 " --bindir=DIR\t\tuser executables [EPREFIX/bin]\n"
368 " --sbindir=DIR\t\tsystem admin executables [EPREFIX/sbin]\n"
369 " --libexecdir=DIR\tprogram executables [EPREFIX/libexec]\n"
370 " --datadir=DIR\t\tread-only architecture-independent data [PREFIX/share]\n"
371 " --sysconfdir=DIR\tread-only single-machine data [PREFIX/etc]\n"
372 " --sharedstatedir=DIR\tmodifiable architecture-independent data [PREFIX/com]\n"
373 " --localstatedir=DIR\tmodifiable single-machine data [PREFIX/var]\n"
374 " --libdir=DIR\t\tobject code libraries [EPREFIX/lib]\n"
375 " --includedir=DIR\tC header files [PREFIX/include]\n"
376 " --oldincludedir=DIR\tC header files for non-gcc [/usr/include]\n"
377 " --gccincludedir=DIR\tGCC internal header files [PREFIX/include]\n"
378 " --custominclude=DIR\tNonstandard header file location (cumulative)\n"
379 " --customlib=DIR\tNonstandard library file location (cumulative)\n"
380 " --infodir=DIR\t\tinfo documentation [PREFIX/info]\n"
381 " --mandir=DIR\t\tman documentation [PREFIX/man]\n"
384 " --build=BUILD\t\tconfigure for building on BUILD [guessed]\n"
385 " --host=HOST\t\tcross-compile to build programs to run on HOST [BUILD]\n"
387 if (VectorSize(g_Components
)) {
388 printf ("\nOptions:\n");
389 foreach (i
, g_ComponentInfos
) {
390 if (!g_ComponentInfos
[i
].m_Description
[0])
392 if (g_ComponentInfos
[i
].m_bDefaultOn
)
393 printf (" --without-%-12s%s\n", g_Components
[i
* 3], g_ComponentInfos
[i
].m_Description
);
395 printf (" --with-%-15s%s\n", g_Components
[i
* 3], g_ComponentInfos
[i
].m_Description
);
399 "\nSome influential environment variables:\n"
400 " CC\t\tC compiler\t\tCFLAGS\n"
401 " CPP\t\tC preprocessor\t\tCPPFLAGS\n"
402 " CXX\t\tC++ compiler\t\tCXXFLAGS\n"
403 " LD\t\tLinker\t\t\tLDFLAGS\n"
405 "Report bugs to " PACKAGE_BUGREPORT
".\n");
409 static void PrintVersion (void)
411 printf (PACKAGE_NAME
" configure " PACKAGE_VERSION
"\n"
412 "\nUsing bsconf package version 0.3\n"
413 "Copyright (c) 2003-2005, Mike Sharov <msharov@users.sourceforge.net>\n"
414 "This configure script and the bsconf package are free software.\n"
415 "Unlimited permission to copy, distribute, and modify is granted.\n");
419 /*- Configuration routines -------------------------------------------*/
421 static void GetConfigVarValues (int argc
, cpchar_t
const* argv
)
426 for (a
= 0; a
< argc
; ++ a
) {
427 if (!compare (argv
[a
], "--"))
430 if (compare (argv
[a
] + apos
, "help"))
432 else if (compare (argv
[a
] + apos
, "version"))
434 else if (compare (argv
[a
] + apos
, "with")) {
436 if (compare (argv
[a
] + apos
, "out"))
439 foreach (cv
, g_ComponentInfos
)
440 if (compare (argv
[a
] + apos
, g_Components
[cv
* 3]))
441 g_ComponentInfos
[cv
].m_bDefaultOn
= (apos
== 7);
443 foreach (cv
, g_ConfigV
)
444 if (compare (argv
[a
] + apos
, g_ConfigV
[cv
]))
448 apos
+= StrLen (g_ConfigV
[cv
]) + 1;
449 cvl
= StrLen (argv
[a
]) - apos
+ 1;
451 buf_copy_n (argv
[a
] + apos
, &g_ConfigVV
[cv
], cvl
);
452 if (cv
== vv_customlib
)
453 buf_copy_n (argv
[a
] + apos
, &g_CustomLibDirs
[g_nCustomLibDirs
++], cvl
);
454 else if (cv
== vv_custominclude
)
455 buf_copy_n (argv
[a
] + apos
, &g_CustomIncDirs
[g_nCustomIncDirs
++], cvl
);
457 if (cv
== vv_prefix
&& compare (S(g_ConfigVV
[cv
]), "/home")) {
458 copy (S(g_ConfigVV
[cv
]), &g_CustomLibDirs
[g_nCustomLibDirs
]);
459 append ("/lib", &g_CustomLibDirs
[g_nCustomLibDirs
++]);
460 copy (S(g_ConfigVV
[cv
]), &g_CustomIncDirs
[g_nCustomIncDirs
]);
461 append ("/include", &g_CustomIncDirs
[g_nCustomIncDirs
++]);
467 static void DefaultConfigVarValue (EVV v
, EVV root
, cpchar_t suffix
)
469 if (!*S(g_ConfigVV
[v
])) {
470 copy (S(g_ConfigVV
[root
]), &g_ConfigVV
[v
]);
471 append (suffix
, &g_ConfigVV
[v
]);
475 static void DetermineHost (void)
481 static const SHostType g_HostTypes
[] = {
482 { "linux", sys_Linux
},
484 { "solaris", sys_Sun
},
485 { "openbsd", sys_Bsd
},
486 { "netbsd", sys_Bsd
},
487 { "freebsd", sys_Bsd
},
489 { "darwin", sys_Mac
},
490 { "alpha", sys_Alpha
}
493 fill_n ((pchar_t
) &g_Uname
, sizeof(struct utsname
), 0);
495 Lowercase (g_Uname
.machine
);
496 Lowercase (g_Uname
.sysname
);
497 copy (g_Uname
.machine
, &g_ConfigVV
[vv_host
]);
498 append ("-", &g_ConfigVV
[vv_host
]);
500 append ("gnu", &g_ConfigVV
[vv_host
]);
502 append ("unknown", &g_ConfigVV
[vv_host
]);
504 append2 ("-", g_Uname
.sysname
, &g_ConfigVV
[vv_host
]);
505 foreach (i
, g_HostTypes
)
506 if (compare (g_Uname
.sysname
, g_HostTypes
[i
].sysname
))
507 g_SysType
= g_HostTypes
[i
].type
;
508 if (compare (g_Uname
.machine
, "alpha"))
509 g_SysType
= sys_Alpha
;
512 static void FillInDefaultConfigVarValues (void)
514 typedef struct _SDefaultPathMap
{
519 static const SDefaultPathMap c_Defaults
[] = {
520 { vv_bindir
, vv_exec_prefix
, "/bin" },
521 { vv_sbindir
, vv_exec_prefix
, "/sbin" },
522 { vv_libexecdir
, vv_prefix
, "/libexec" },
523 { vv_datadir
, vv_prefix
, "/share" },
524 { vv_sysconfdir
, vv_prefix
, "/etc" },
525 { vv_sharedstatedir
, vv_prefix
, "/com" },
526 { vv_localstatedir
, vv_prefix
, "/var" },
527 { vv_libdir
, vv_exec_prefix
, "/lib" },
528 { vv_gcclibdir
, vv_exec_prefix
, "/lib" },
529 { vv_includedir
, vv_prefix
, "/include" },
530 { vv_gccincludedir
, vv_prefix
, "/include" },
531 { vv_infodir
, vv_prefix
, "/info" },
532 { vv_mandir
, vv_prefix
, "/man" }
536 if (!*S(g_ConfigVV
[vv_prefix
]))
537 copy ("/usr/local", &g_ConfigVV
[vv_prefix
]);
538 else if (S(g_ConfigVV
[vv_prefix
])[0] == '/' && !S(g_ConfigVV
[vv_prefix
])[1])
539 g_ConfigVV
[vv_prefix
].data
[0] = 0;
540 if (!*S(g_ConfigVV
[vv_exec_prefix
]))
541 DefaultConfigVarValue (vv_exec_prefix
, vv_prefix
, "");
542 else if (S(g_ConfigVV
[vv_exec_prefix
])[0] == '/' && !S(g_ConfigVV
[vv_exec_prefix
])[1])
543 g_ConfigVV
[vv_exec_prefix
].data
[0] = 0;
544 if (!*S(g_ConfigVV
[vv_oldincludedir
]))
545 copy ("/usr/include", &g_ConfigVV
[vv_oldincludedir
]);
547 foreach (i
, c_Defaults
)
548 DefaultConfigVarValue (c_Defaults
[i
].var
, c_Defaults
[i
].base
, c_Defaults
[i
].path
);
550 if (!*S(g_ConfigVV
[vv_prefix
]))
551 copy ("/usr", &g_ConfigVV
[vv_prefix
]);
552 if (!*S(g_ConfigVV
[vv_exec_prefix
]))
553 copy ("/usr", &g_ConfigVV
[vv_exec_prefix
]);
555 if (!*S(g_ConfigVV
[vv_host
]))
557 if (!*S(g_ConfigVV
[vv_build
]))
558 copy (S(g_ConfigVV
[vv_host
]), &g_ConfigVV
[vv_build
]);
561 static cpchar_t
CopyPathEntry (cpchar_t pi
, pbuf_t dest
)
564 while (pi
[pil
] && pi
[pil
] != ':') ++ pil
;
565 buf_copy_n (pi
, dest
, pil
);
566 return (*(pi
+= pil
) ? ++pi
: NULL
);
569 static int IsBadInstallDir (cpchar_t match
)
571 static const char c_BadDirs
[][10] = { "/etc", "/c", "/C", "/usr/etc", "/sbin", "/usr/sbin", "/usr/ucb" };
573 foreach (i
, c_BadDirs
)
574 if (compare (match
, c_BadDirs
[i
]))
579 static void FindPrograms (void)
583 SBuf match
= NULL_BUF
;
585 path
= getenv ("PATH");
589 foreach (i
, g_ProgLocs
) {
592 for (pi
= path
; pi
; pi
= CopyPathEntry (pi
, &match
)) {
593 /* Ignore "bad" versions of install, like autoconf does. */
594 if (compare (g_ProgVars
[i
* 4 + 1], "install") && IsBadInstallDir (S(match
)))
596 append2 ("/", g_ProgVars
[i
* 4 + 1], &match
);
597 if (access (S(match
), X_OK
) == 0) {
602 if (count
&& compare (g_ProgVars
[i
* 4 + 1], "install"))
603 copy (S(match
), &g_ProgLocs
[i
]);
605 copy (g_ProgVars
[i
* 4 + 2 + !count
], &g_ProgLocs
[i
]);
610 static void SubstitutePaths (void)
612 SBuf match
= NULL_BUF
;
614 foreach (cv
, g_ConfigV
) {
615 MakeSubstString (g_ConfigV
[cv
], &match
);
616 Substitute (S(match
), S(g_ConfigVV
[cv
]));
621 static void SubstituteCFlags (void)
626 for (j
= 0; j
< g_nCustomIncDirs
; ++ j
)
627 append2 (" -I", S(g_CustomIncDirs
[j
]), &buf
);
628 Substitute ("@CUSTOMINCDIR@", S(buf
));
631 for (j
= 0; j
< g_nCustomLibDirs
; ++ j
)
632 append2 (" -L", S(g_CustomLibDirs
[j
]), &buf
);
633 Substitute ("@CUSTOMLIBDIR@", S(buf
));
637 if (g_CpuCapBits
& (1 << 23))
638 append (" -mmmx", &buf
);
639 if (g_SysType
== sys_Linux
)
640 if (g_CpuCapBits
& ((1 << 22) | (1 << 25)))
641 append (" -msse -mfpmath=sse", &buf
);
642 if (g_CpuCapBits
& (1 << 26))
643 append (" -msse2", &buf
);
644 if (g_CpuCapBits
& ((1 << 30) | (1 << 31)))
645 append (" -m3dnow", &buf
);
647 Substitute ("@PROCESSOR_OPTS@", S(buf
));
650 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
651 copy (" --param max-inline-insns-single=1024", &buf
);
652 append (" \\\n\t\t--param large-function-growth=65535", &buf
);
653 append (" \\\n\t\t--param inline-unit-growth=1024", &buf
);
655 copy ("-finline-limit=65535", &buf
);
658 append (" \\\n\t\t-fvisibility-inlines-hidden", &buf
);
661 Substitute ("@INLINE_OPTS@", S(buf
));
664 Substitute ("-fPIC", "");
669 static void SubstituteEnvironment (int bForce
)
671 SBuf match
= NULL_BUF
;
675 foreach (i
, g_EnvVars
) {
676 envval
= getenv (g_EnvVars
[i
]);
682 MakeSubstString (g_EnvVars
[i
], &match
);
683 Substitute (S(match
), envval
);
688 static void SubstitutePrograms (void)
691 SBuf match
= NULL_BUF
;
692 foreach (i
, g_ProgLocs
) {
693 MakeSubstString (g_ProgVars
[i
* 4], &match
);
694 Substitute (S(match
), S(g_ProgLocs
[i
]));
699 #if defined(__GNUC__) && (__i386__ || __x86_64) && !defined(__PIC__)
700 static uint
cpuid_supported (void)
702 unsigned long forig
, fnew
;
703 /* Pop flags, toggle ID bit, push, pop. cpuid supported if changed. */
704 asm ("pushf\n\tpop\t%0\n\t"
705 "mov\t%0, %1\n\txor\t$0x200000, %0\n\t"
706 "push\t%0\n\tpopf\n\tpushf\n\tpop\t%0"
707 : "=r"(fnew
), "=r"(forig
));
708 return (fnew
!= forig
);
711 static uint
cpuid (void)
713 #define i_cpuid(a,r,c,d) asm("cpuid":"=a"(r),"=c"(c),"=d"(d):"0"(a):"ebx")
714 const uint amdBits
= 0xC9480000, extFeatures
= 0x80000000, amdExtensions
= 0x80000001;
716 if (!cpuid_supported()) return (0);
717 i_cpuid (0, r
, c
, d
);
719 i_cpuid (1, r
, c
, d
); /* Ask for feature list */
720 caps
= (d
& ~amdBits
);
721 i_cpuid (extFeatures
, r
, c
, d
);
722 if (r
!= extFeatures
) {
723 i_cpuid (amdExtensions
, r
, c
, d
);
729 static uint
cpuid (void) { return (0); }
732 static void SubstituteCpuCaps (void)
736 char m_Disabled
[26];
739 static const SCpuCaps s_CpuCaps
[] = {
740 { 0, "#undef CPU_HAS_FPU", "#define CPU_HAS_FPU 1" },
741 { 2, "#undef CPU_HAS_EXT_DEBUG", "#define CPU_HAS_EXT_DEBUG 1" },
742 { 4, "#undef CPU_HAS_TIMESTAMPC", "#define CPU_HAS_TIMESTAMPC 1" },
743 { 5, "#undef CPU_HAS_MSR", "#define CPU_HAS_MSR 1" },
744 { 8, "#undef CPU_HAS_CMPXCHG8", "#define CPU_HAS_CMPXCHG8 1" },
745 { 9, "#undef CPU_HAS_APIC", "#define CPU_HAS_APIC 1" },
746 { 11, "#undef CPU_HAS_SYSCALL", "#define CPU_HAS_SYSCALL 1" },
747 { 12, "#undef CPU_HAS_MTRR", "#define CPU_HAS_MTRR 1" },
748 { 15, "#undef CPU_HAS_CMOV", "#define CPU_HAS_CMOV 1" },
749 { 16, "#undef CPU_HAS_FCMOV", "#define CPU_HAS_FCMOV 1" },
750 { 22, "#undef CPU_HAS_SSE ", "#define CPU_HAS_SSE 1" },
751 { 23, "#undef CPU_HAS_MMX", "#define CPU_HAS_MMX 1" },
752 { 24, "#undef CPU_HAS_FXSAVE", "#define CPU_HAS_FXSAVE 1" },
753 { 25, "#undef CPU_HAS_SSE ", "#define CPU_HAS_SSE 1" },
754 { 26, "#undef CPU_HAS_SSE2", "#define CPU_HAS_SSE2 1" },
755 { 30, "#undef CPU_HAS_EXT_3DNOW", "#define CPU_HAS_EXT_3DNOW 1" },
756 { 31, "#undef CPU_HAS_3DNOW", "#define CPU_HAS_3DNOW 1" }
759 g_CpuCapBits
= cpuid();
760 foreach (i
, s_CpuCaps
)
761 if (g_CpuCapBits
& (1 << s_CpuCaps
[i
].m_Bit
))
762 Substitute (s_CpuCaps
[i
].m_Disabled
, s_CpuCaps
[i
].m_Enabled
);
765 static void SubstituteHostOptions (void)
767 static const short int boCheck
= 0x0001;
768 static const char boNames
[2][16] = { "BIG_ENDIAN", "LITTLE_ENDIAN" };
771 if (g_SysType
== sys_Sun
)
773 Substitute ("-Wredundant-decls", "-Wno-redundant-decls");
775 if (g_SysType
== sys_Bsd
) {
776 Substitute (" @libgcc_eh@", "");
777 Substitute ("#define WITHOUT_LIBSTDCPP 1", "#undef WITHOUT_LIBSTDCPP");
778 Substitute ("NOLIBSTDCPP\t= -nodefaultlibs ", "#NOLIBSTDCPP\t= -nodefaultlibs");
779 Substitute ("-Wredundant-decls", "-Wno-redundant-decls");
780 Substitute ("-Winline", "-Wno-inline");
783 if ((g_SysType
== sys_Linux
) | (g_SysType
== sys_Bsd
))
784 Substitute ("@SHBLDFL@", "-shared -Wl,-soname=${LIBSOLNK}");
785 else if (g_SysType
== sys_Mac
)
786 Substitute ("@SHBLDFL@", "-Wl,-single_module -compatibility_version 1 -current_version 1 -install_name ${LIBSOLNK} -Wl,-Y,1455 -dynamiclib -mmacosx-version-min=10.4");
787 else if (g_SysType
== sys_Sun
)
788 Substitute ("@SHBLDFL@", "-G");
790 Substitute ("BUILD_SHARED\t= 1 ", "#BUILD_SHARED\t= 1");
791 Substitute ("#BUILD_STATIC\t= 1", "BUILD_STATIC\t= 1 ");
794 if (g_SysType
== sys_Mac
) {
795 Substitute (" @libgcc_eh@", "");
796 Substitute ("@libgcc@", "@libsupc++@ @libgcc@");
797 Substitute ("@SYSWARNS@", "-Wno-long-double");
798 Substitute ("lib${LIBNAME}.so", "lib${LIBNAME}.dylib");
799 Substitute ("${LIBSO}.${MAJOR}.${MINOR}.${BUILD}", "lib${LIBNAME}.${MAJOR}.${MINOR}.${BUILD}.dylib");
800 Substitute ("${LIBSO}.${MAJOR}.${MINOR}", "lib${LIBNAME}.${MAJOR}.${MINOR}.dylib");
801 Substitute ("${LIBSO}.${MAJOR}", "lib${LIBNAME}.${MAJOR}.dylib");
803 Substitute ("@SYSWARNS@", "");
805 if (g_SysType
!= sys_Sun
)
806 Substitute ("#undef HAVE_THREE_CHAR_TYPES", "#define HAVE_THREE_CHAR_TYPES 1");
808 Substitute ("#undef RETSIGTYPE", "#define RETSIGTYPE void");
809 Substitute ("#undef const", "/* #define const */");
810 Substitute ("#undef inline", "/* #define inline __inline */");
811 Substitute ("#undef off_t", "/* typedef long off_t; */");
812 Substitute ("#undef size_t", "/* typedef long size_t; */");
814 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_CHAR %zd", sizeof(char));
815 Substitute ("#undef SIZE_OF_CHAR", buf
);
816 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_SHORT %zd", sizeof(short));
817 Substitute ("#undef SIZE_OF_SHORT", buf
);
818 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_INT %zd", sizeof(int));
819 Substitute ("#undef SIZE_OF_INT", buf
);
820 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_LONG %zd", sizeof(long));
821 Substitute ("#undef SIZE_OF_LONG ", buf
);
822 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_POINTER %zd", sizeof(void*));
823 Substitute ("#undef SIZE_OF_POINTER ", buf
);
824 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_SIZE_T %zd", sizeof(size_t));
825 Substitute ("#undef SIZE_OF_SIZE_T ", buf
);
826 if (g_SysType
== sys_Alpha
|| g_SysType
== sys_Mac
)
827 Substitute ("#undef SIZE_OF_BOOL ", "#define SIZE_OF_BOOL SIZE_OF_LONG");
829 Substitute ("#undef SIZE_OF_BOOL ", "#define SIZE_OF_BOOL SIZE_OF_CHAR");
830 if ((sizeof(size_t) == sizeof(unsigned long) &&
831 sizeof(size_t) != sizeof(uint
)) || g_SysType
== sys_Mac
)
832 Substitute ("#undef SIZE_T_IS_LONG", "#define SIZE_T_IS_LONG 1");
833 #if defined(__GNUC__) || (__WORDSIZE == 64) || defined(__ia64__)
834 if (g_SysType
!= sys_Bsd
)
835 Substitute ("#undef HAVE_INT64_T", "#define HAVE_INT64_T 1");
837 #if defined(__GNUC__) || defined(__GLIBC_HAVE_LONG_LONG)
838 Substitute ("#undef HAVE_LONG_LONG", "#define HAVE_LONG_LONG 1");
839 snprintf (buf
, VectorSize(buf
), "#define SIZE_OF_LONG_LONG %zd", sizeof(long long));
840 Substitute ("#undef SIZE_OF_LONG_LONG", buf
);
842 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
843 Substitute ("#undef HAVE_VECTOR_EXTENSIONS", "#define HAVE_VECTOR_EXTENSIONS 1");
845 Substitute ("-Wshadow ", "");
848 Substitute ("#undef LSTAT_FOLLOWS_SLASHED_SYMLINK", "#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1");
849 Substitute ("#undef HAVE_STAT_EMPTY_STRING_BUG", "/* #undef HAVE_STAT_EMPTY_STRING_BUG */");
851 if (g_SysType
== sys_Linux
)
852 Substitute ("#undef HAVE_RINTF", "#define HAVE_RINTF 1");
854 Substitute ("@BYTE_ORDER@", boNames
[(uint
)(*((const char*)&boCheck
))]);
857 static void SubstituteCustomVars (void)
860 SBuf match
= NULL_BUF
;
861 foreachN (i
, g_CustomVars
, 2) {
862 MakeSubstString (g_CustomVars
[i
* 2], &match
);
863 Substitute (S(match
), g_CustomVars
[i
* 2 + 1]);
868 static void SubstituteHeaders (void)
872 SBuf defaultPath
= NULL_BUF
, match
= NULL_BUF
;
874 copy (S(g_ConfigVV
[vv_includedir
]), &defaultPath
);
875 append2 (":", S(g_ConfigVV
[vv_oldincludedir
]), &defaultPath
);
876 append2 (":", S(g_ConfigVV
[vv_gccincludedir
]), &defaultPath
);
877 for (i
= 0; i
!= (uint
) g_nCustomIncDirs
; ++ i
)
878 append2 (":", S(g_CustomIncDirs
[i
]), &defaultPath
);
879 foreachN (i
, g_Headers
, 3) {
880 for (pi
= S(defaultPath
); pi
; pi
= CopyPathEntry (pi
, &match
)) {
881 append2 ("/", g_Headers
[i
* 3], &match
);
882 if (access (S(match
), R_OK
) == 0)
883 Substitute (g_Headers
[i
* 3 + 1], g_Headers
[i
* 3 + 2]);
887 buf_free (&defaultPath
);
890 static void SubstituteLibs (void)
892 static const char g_LibSuffixes
[][8] = { ".a", ".so", ".la", ".dylib" };
895 SBuf defaultPath
= NULL_BUF
, match
= NULL_BUF
;
897 copy ("/lib:/usr/lib:/usr/local/lib", &defaultPath
);
898 pi
= getenv ("LD_LIBRARY_PATH");
900 append2 (":", pi
, &defaultPath
);
901 append2 (":", S(g_ConfigVV
[vv_libdir
]), &defaultPath
);
902 append2 (":", S(g_ConfigVV
[vv_gcclibdir
]), &defaultPath
);
903 for (i
= 0; i
!= (uint
) g_nCustomLibDirs
; ++ i
)
904 append2 (":", S(g_CustomLibDirs
[i
]), &defaultPath
);
906 foreachN (i
, g_Libs
, 3) {
908 for (pi
= S(defaultPath
); pi
; pi
= CopyPathEntry (pi
, &match
)) {
909 foreach (k
, g_LibSuffixes
) {
910 CopyPathEntry (pi
, &match
);
911 append2 ("/lib", g_Libs
[i
* 3], &match
);
912 append (g_LibSuffixes
[k
], &match
);
913 if (access (S(match
), R_OK
) == 0)
917 copy ("@lib", &match
);
918 append2 (g_Libs
[i
* 3], "@", &match
);
919 Substitute (S(match
), g_Libs
[i
* 3 + 1 + ok
]);
922 buf_free (&defaultPath
);
925 static void SubstituteFunctions (void)
928 foreachN (i
, g_Functions
, 3)
929 Substitute (g_Functions
[i
* 3 + 1], g_Functions
[i
* 3 + 2]);
930 if ((g_SysType
== sys_Mac
) | (g_SysType
== sys_Bsd
))
931 Substitute ("#define HAVE_STRSIGNAL 1", "#undef HAVE_STRSIGNAL");
932 if (g_SysType
== sys_Bsd
)
933 Substitute ("#define HAVE_VA_COPY 1", "#undef HAVE_VA_COPY");
936 static void SubstituteComponents (void)
939 foreachN (i
, g_Components
, 3) {
940 isOn
= g_ComponentInfos
[i
].m_bDefaultOn
;
941 Substitute (g_Components
[i
* 3 + 1 + !isOn
], g_Components
[i
* 3 + 1 + isOn
]);
945 /*--------------------------------------------------------------------*/
947 int main (int argc
, const char* const* argv
)
950 GetConfigVarValues (--argc
, ++argv
);
951 FillInDefaultConfigVarValues();
954 SubstituteComponents();
955 SubstituteHostOptions();
959 SubstituteEnvironment (0);
960 SubstitutePrograms();
963 SubstituteFunctions();
964 SubstituteCustomVars();
965 SubstituteEnvironment (1);
967 ApplySubstitutions();