1
0
Fork 0
sattools/qfits/sysconf.c

1028 lines
22 KiB
C

/*----------------------------------------------------------------------------*/
/**
@file sysconf.c
@author Nicolas Devillard
@date February 2001
@version $Revision: 1.33 $
@brief configure-like in C.
*/
/*----------------------------------------------------------------------------*/
/*
$Id: sysconf.c,v 1.33 2005/02/24 15:59:59 yjung Exp $
$Author: yjung $
$Date: 2005/02/24 15:59:59 $
$Revision: 1.33 $
*/
/*---------------------------------------------------------------------------
Includes
---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MAXSTRSZ 512
#define MACROS_FILE "config.make"
#define HEADER_FILE "config.h"
#define PREFIX_DEFAULT "/usr/local"
#define COMPILER_AUTO 0
#define COMPILER_CC 1
#define COMPILER_GCC 2
#define XMEMDEBUG " -DXMEMORY_DEBUG=1"
/* Global variable */
struct
{
/* List of supported OS's */
enum
{
os_linux,
os_cygwin,
os_hp08,
os_hp09,
os_hp10,
os_hp11,
os_solaris,
os_irix,
os_aix,
os_dec,
os_bsd,
os_darwin
} local_os;
char sysname[MAXSTRSZ];
char release[MAXSTRSZ];
char machine[MAXSTRSZ];
/* Bits per byte on this machine */
int bits_per_byte;
/* Big endian machine? */
int big_endian;
/* x86 architecture? */
int arch_x86;
/* CPU type: 386, 486, 586, 686 */
int cpu_x86;
/* Compile with debug options on */
int debug_compile;
/* Compile with warnings on */
int lint_compile;
/* Compiler type: native cc or gcc */
int compiler;
/* Compile with threads */
int with_threads;
/* Number of detected CPUs */
int ncpus;
/* Compile static library */
int lib_static;
/* Compile dynamic library */
int lib_dynamic;
/* Prefix for installation */
char *prefix;
/* With or without xmemory handling */
int xmemory_mode;
/* Maximum number of pointers allowed */
int max_ptrs;
} config;
/*
* Check that all files present in the list of names are
* somewhere present in the list of paths.
*/
int
config_findfiles (paths, names)
char **paths;
char **names;
{
struct stat sta;
char spath[MAXSTRSZ];
int i, j;
int nfound;
/* Loop on all paths */
i = 0;
while (paths[i])
{
printf ("searching in %s...\n", paths[i]);
/* Loop on all file names */
j = 0;
nfound = 0;
while (names[j])
{
sprintf (spath, "%s/%s", paths[i], names[j]);
if (stat (spath, &sta) == 0)
{
nfound++;
}
j++;
}
if (j == nfound)
{
printf ("found in %s\n", paths[i]);
return i;
}
i++;
}
return -1;
}
/* Guess local OS name and potentially release number */
void
detect_config ()
{
struct utsname name;
int i;
unsigned char c;
int x;
if (config.sysname[0] == 0)
{
printf ("detecting local OS............. ");
/* Get machine OS type and release number */
if (uname (&name) == -1)
{
printf ("error calling uname\n");
exit (-1);
}
printf ("%s %s", name.sysname, name.release);
strcpy (config.sysname, name.sysname);
strcpy (config.release, name.release);
strcpy (config.machine, name.machine);
}
else
{
printf ("forcing config for OS.......... %s %s",
config.sysname, config.release);
}
/* Lowercase everything */
i = 0;
while (config.sysname[i] != 0)
{
config.sysname[i] = tolower (config.sysname[i]);
i++;
}
i = 0;
while (config.release[i] != 0)
{
config.release[i] = tolower (config.release[i]);
i++;
}
/* Switch on OS type and release number */
if (strstr (config.sysname, "linux") != NULL)
{
config.local_os = os_linux;
printf (" - linux\n");
}
else if (strstr (config.sysname, "cygwin") != NULL)
{
config.local_os = os_cygwin;
printf (" - cygwin\n");
}
else if (strstr (config.sysname, "hp") != NULL)
{
if (strstr (config.release, "8.") != NULL)
{
config.local_os = os_hp08;
printf (" - hpux_08\n");
}
else if (strstr (config.release, "9.") != NULL)
{
config.local_os = os_hp09;
printf (" - hpux_09\n");
}
else if (strstr (config.release, "10.") != NULL)
{
config.local_os = os_hp10;
printf (" - hpux_10\n");
}
else if (strstr (config.release, "11.") != NULL)
{
config.local_os = os_hp11;
printf (" - hpux_11\n");
}
}
else if ((strstr (config.sysname, "sun") != NULL) ||
(strstr (config.sysname, "solaris") != NULL))
{
config.local_os = os_solaris;
printf (" - solaris\n");
}
else if (strstr (config.sysname, "irix") != NULL)
{
config.local_os = os_irix;
printf (" - irix\n");
}
else if (strstr (config.sysname, "aix") != NULL)
{
config.local_os = os_aix;
printf (" - aix\n");
}
else if (strstr (config.sysname, "osf") != NULL)
{
config.local_os = os_dec;
printf (" - osf/1\n");
}
else if (strstr (config.sysname, "bsd") != NULL)
{
config.local_os = os_bsd;
printf (" - %s\n", config.sysname);
}
else if (strstr (config.sysname, "darwin") != NULL)
{
config.local_os = os_darwin;
printf (" - %s\n", config.sysname);
}
else
{
printf ("cannot identify your OS\n");
printf ("Use the option --os=NAME to force an OS type\n");
exit (-1);
}
/* Find out about x86 architectures */
if ((config.machine[0] == 'i') && (strstr (config.machine, "86") != NULL))
{
config.arch_x86 = 1;
config.cpu_x86 = atoi (config.machine + 1);
printf ("detected x86 architecture...... %d\n", config.cpu_x86);
}
else
{
config.arch_x86 = 0;
printf ("detected x86 architecture...... no\n");
}
/* Compute number of bits in a byte on this machine */
printf ("computing bits per byte........ ");
c = 1;
i = 0;
while (c)
{
c <<= 1;
i++;
}
config.bits_per_byte = i;
printf ("%d\n", i);
/* Detect endian-ness */
printf ("detecting byte-order........... ");
x = 1;
x = (*(char *) &x);
config.big_endian = !x;
if (config.big_endian)
{
printf ("big endian (motorola)\n");
}
else
{
printf ("little endian (intel)\n");
}
return;
}
/* Locate a program in the user's PATH */
int
locate_program (pname)
char *pname;
{
int i, j, lg;
char *path;
char buf[MAXSTRSZ];
path = getenv ("PATH");
if (path != NULL)
{
for (i = 0; path[i];)
{
for (j = i; (path[j]) && (path[j] != ':'); j++);
lg = j - i;
strncpy (buf, path + i, lg);
if (lg == 0)
buf[lg++] = '.';
buf[lg++] = '/';
strcpy (buf + lg, pname);
if (access (buf, X_OK) == 0)
{
printf ("using [%s]\n", buf);
return 1;
}
buf[0] = 0;
i = j;
if (path[i] == ':')
i++;
}
}
else
{
/* No PATH variable: abort with an error */
return -1;
}
/* If the buffer is still empty, the command was not found */
if (buf[0] == 0)
return 0;
/* Otherwise Ok */
return 1;
}
void
make_config_make ()
{
FILE *sysc;
/* Set compiler name */
printf ("looking for a C compiler....... ");
if (getenv ("PATH") == NULL)
{
printf ("error: undefined PATH variable, cannot locate a compiler\n");
exit (-1);
}
/* Open output sysconf */
if ((sysc = fopen (MACROS_FILE, "w")) == NULL)
{
printf ("cannot create %s: aborting compilation", MACROS_FILE);
exit (-1);
}
/* In automatic mode, find out which compiler to use */
if (config.compiler == COMPILER_AUTO)
{
switch (config.local_os)
{
/* Use gcc under Linux, BSD, Cygwin & IRIX */
case os_linux:
case os_cygwin:
case os_bsd:
case os_irix:
config.compiler = COMPILER_GCC;
break;
/* All others use 'cc' (default) */
default:
config.compiler = COMPILER_CC;
break;
}
}
/* Make sure the compiler can be found */
if (config.compiler == COMPILER_CC)
{
if (locate_program ("cc") != 1)
{
printf ("cannot locate cc\n");
/* Try out with gcc */
config.compiler = COMPILER_GCC;
}
}
if (config.compiler == COMPILER_GCC)
{
if (locate_program ("gcc") != 1)
{
printf ("cannot locate gcc\n");
exit (-1);
}
}
/* Set compiler name and cflags */
switch (config.compiler)
{
case COMPILER_CC:
fprintf (sysc, "CC = cc\n");
fprintf (sysc, "CFLAGS = ");
if (config.xmemory_mode == 0)
{
fprintf (sysc, "-DXMEMORY_MODE=%d ", config.xmemory_mode);
fprintf (sysc, "-DXMEMORY_MAXPTRS=1 ");
}
else if (config.xmemory_mode == 1)
{
fprintf (sysc, "-DXMEMORY_MODE=%d ", config.xmemory_mode);
fprintf (sysc, "-DXMEMORY_MAXPTRS=1 ");
}
else if (config.xmemory_mode == 2)
{
fprintf (sysc, "-DXMEMORY_MODE=%d ", config.xmemory_mode);
if (config.max_ptrs > 0)
{
fprintf (sysc, "-DXMEMORY_MAXPTRS=%d ", config.max_ptrs);
}
}
else if (config.xmemory_mode < 0)
{
if (config.max_ptrs > 0)
{
fprintf (sysc, "-DXMEMORY_MAXPTRS=%d ", config.max_ptrs);
}
}
switch (config.local_os)
{
case os_hp08:
case os_hp09:
case os_hp10:
if (config.with_threads)
{
printf ("threads not supported on this platform\n");
}
if (config.debug_compile)
{
fprintf (sysc, "-Ae -g%s\n", XMEMDEBUG);
}
else
{
fprintf (sysc, "-Ae -O\n");
}
fprintf (sysc, "RELOC = +z\n");
fprintf (sysc, "SHARED = -b\n");
break;
case os_hp11:
if (config.with_threads)
{
fprintf (sysc, "-lpthread ");
}
if (config.debug_compile)
{
fprintf (sysc, "-g%s\n", XMEMDEBUG);
}
else
{
fprintf (sysc, "-O\n");
}
fprintf (sysc, "RELOC = +z\n");
fprintf (sysc, "SHARED = -b\n");
break;
case os_solaris:
if (config.with_threads)
{
fprintf (sysc, "-mt -lpthread ");
}
if (config.debug_compile)
{
fprintf (sysc, "-g%s\n", XMEMDEBUG);
}
else
{
fprintf (sysc, "-xO5\n");
}
fprintf (sysc, "RELOC = -G\n");
fprintf (sysc, "SHARED = -G\n");
break;
case os_dec:
if (config.with_threads)
{
printf ("threads not supported on this platform\n");
}
if (config.debug_compile)
{
fprintf (sysc, "-g%s\n", XMEMDEBUG);
}
else
{
fprintf (sysc, "-O\n");
}
fprintf (sysc, "RELOC =\n");
fprintf (sysc, "SHARED = -shared -expect_unresolved \"*\"\n");
break;
case os_irix:
case os_aix:
case os_bsd:
if (config.with_threads)
{
printf ("threads not supported on this platform\n");
}
if (config.debug_compile)
{
fprintf (sysc, "-g%s\n", XMEMDEBUG);
}
else
{
fprintf (sysc, "-O\n");
}
fprintf (sysc, "RELOC =\n");
fprintf (sysc, "SHARED =\n");
break;
case os_cygwin:
case os_linux:
/* cc with Linux? Why not! */
if (config.with_threads)
{
fprintf (sysc, "-pthread ");
}
if (config.debug_compile)
{
fprintf (sysc, "-g%s\n", XMEMDEBUG);
}
else
{
fprintf (sysc, "-O3\n");
}
fprintf (sysc, "RELOC = -fpic\n");
fprintf (sysc, "SHARED = -shared\n");
break;
case os_darwin:
/* Darwin uses gcc but calls it 'cc' */
if (config.with_threads)
{
fprintf (sysc, "-pthread ");
}
if (config.debug_compile)
{
fprintf (sysc, "-g%s\n", XMEMDEBUG);
}
else
{
fprintf (sysc, "-O3\n");
}
fprintf (sysc, "RELOC = -fPIC\n");
fprintf (sysc, "SHARED = -shared\n");
break;
default:
printf ("error: unsupported OS\n");
exit (-1);
}
break;
case COMPILER_GCC:
fprintf (sysc, "CC = gcc\n");
fprintf (sysc, "CFLAGS = ");
if (config.xmemory_mode == 0)
{
fprintf (sysc, "-DXMEMORY_MODE=%d ", config.xmemory_mode);
fprintf (sysc, "-DXMEMORY_MAXPTRS=1 ");
}
else if (config.xmemory_mode == 1)
{
fprintf (sysc, "-DXMEMORY_MODE=%d ", config.xmemory_mode);
fprintf (sysc, "-DXMEMORY_MAXPTRS=1 ");
}
else if (config.xmemory_mode == 2)
{
fprintf (sysc, "-DXMEMORY_MODE=%d ", config.xmemory_mode);
if (config.max_ptrs > 0)
{
fprintf (sysc, "-DXMEMORY_MAXPTRS=%d ", config.max_ptrs);
}
}
else if (config.xmemory_mode < 0)
{
if (config.max_ptrs > 0)
{
fprintf (sysc, "-DXMEMORY_MAXPTRS=%d ", config.max_ptrs);
}
}
if (config.with_threads)
{
fprintf (sysc, "-pthread ");
}
if (config.lint_compile)
{
fprintf (sysc, " -Wall -pedantic ");
}
if (config.debug_compile)
{
fprintf (sysc, "-g%s\n", XMEMDEBUG);
}
else
{
fprintf (sysc, "-O3\n");
}
if (config.local_os != os_cygwin)
fprintf (sysc, "RELOC = -fPIC -DPIC\n");
fprintf (sysc, "SHARED = -shared\n");
break;
default:
printf ("error in compiler option switch: aborting\n");
exit (-1);
break;
}
if (config.debug_compile)
{
printf (" in debug mode\n");
}
else
{
printf (" all optimizations on\n");
}
if (config.lint_compile)
{
printf (" with all warnings\n");
}
/* LFLAGS */
fprintf (sysc, "LFLAGS = ");
switch (config.local_os)
{
case os_hp10:
case os_hp11:
fprintf (sysc, "-Wl,+vnocompatwarnings ");
break;
default:
break;
}
fprintf (sysc, "\n");
/* DYNSUF */
switch (config.local_os)
{
case os_hp08:
case os_hp09:
case os_hp10:
case os_hp11:
fprintf (sysc, "DYNSUF = sl\n");
break;
case os_darwin:
fprintf (sysc, "DYNSUF = so\n");
break;
default:
fprintf (sysc, "DYNSUF = so\n");
break;
}
/* STRIP */
if (config.debug_compile)
{
fprintf (sysc, "STRIP = true\n");
}
else
{
fprintf (sysc, "STRIP = strip\n");
}
/* TARGETS */
fprintf (sysc, "TARGETS =");
printf ("static library................. %s\n",
config.lib_static ? "yes" : "no");
if (config.lib_static)
{
fprintf (sysc, " static");
}
printf ("shared library................. %s\n",
config.lib_dynamic ? "yes" : "no");
if (config.lib_dynamic)
{
fprintf (sysc, " dynamic");
}
fprintf (sysc, "\n");
/* PREFIX */
fprintf (sysc, "prefix = %s\n",
config.prefix ? config.prefix : PREFIX_DEFAULT);
printf ("setting installation prefix as: [%s]\n",
config.prefix ? config.prefix : PREFIX_DEFAULT);
fclose (sysc);
}
void
make_config_h ()
{
FILE *out;
out = fopen (HEADER_FILE, "w");
if (out == NULL)
{
printf ("cannot create header file %s: aborting", HEADER_FILE);
return;
}
fprintf (out,
"/* This file automatically generated */\n"
"#ifndef _CONFIG_H_\n"
"#define _CONFIG_H_\n"
"\n"
"%s", config.big_endian ? "#define WORDS_BIGENDIAN 1\n" : "\n");
/* Generate SIZEOF macros for basic types */
printf ("detecting basic size types\n");
fprintf (out,
"#define SIZEOF_CHAR %d\n"
"#define SIZEOF_SHORT %d\n"
"#define SIZEOF_INT %d\n"
"#define SIZEOF_LONG %d\n"
"#define SIZEOF_FLOAT %d\n"
"#define SIZEOF_DOUBLE %d\n",
sizeof (char),
sizeof (short),
sizeof (int), sizeof (long), sizeof (float), sizeof (double));
printf ("sizeof(char)................... %d\n"
"sizeof(short).................. %d\n"
"sizeof(int).................... %d\n"
"sizeof(long)................... %d\n"
"sizeof(float).................. %d\n"
"sizeof(double)................. %d\n",
sizeof (char),
sizeof (short),
sizeof (int), sizeof (long), sizeof (float), sizeof (double));
/* Do not output CHAR_BIT on AIX */
if (config.local_os != os_aix)
{
fprintf (out,
"\n"
"#ifndef CHAR_BIT\n"
"#define CHAR_BIT\t%d\n"
"#endif\n" "\n\n", config.bits_per_byte);
}
if (config.arch_x86)
{
fprintf (out, "#define CPU_X86 %d\n", config.cpu_x86);
}
if (config.with_threads)
{
fprintf (out, "#define HAS_PTHREADS 1\n");
}
fprintf (out, "\n");
switch (config.local_os)
{
case os_hp08:
case os_hp09:
case os_hp10:
case os_hp11:
fprintf (out, "#define OS_HPUX 1\n");
break;
case os_linux:
fprintf (out, "#define OS_LINUX 1\n");
break;
case os_cygwin:
fprintf (out, "#define OS_CYGWIN 1\n");
break;
case os_irix:
fprintf (out, "#define OS_IRIX 1\n");
break;
case os_aix:
fprintf (out, "#define OS_AIX 1\n");
break;
case os_dec:
fprintf (out, "#define OS_DEC 1\n");
break;
case os_solaris:
fprintf (out, "#define OS_SOLARIS 1\n");
break;
case os_bsd:
fprintf (out, "#define OS_BSD 1\n");
break;
case os_darwin:
fprintf (out, "#define OS_DARWIN 1\n");
break;
default:
fprintf (out, "#define OS_UNKNOWN 1\n");
break;
}
fprintf (out, "#endif\n");
fclose (out);
printf ("done\n");
return;
}
void
help ()
{
printf ("\n\n"
"***** qfits configure help\n"
"Use: configure [options]\n"
"\n"
"options are:\n"
"\t--debug Compile modules in debug mode\n"
"\t--help Get this help\n"
"\n"
"\t--with-cc Force compilation with local cc\n"
"\t--with-gcc Force compilation with gcc\n"
"\n"
"\t--enable-static Compile static library (default)\n"
"\t--enable-shared Compile shared library\n"
"\t--disable-shared Do not compile shared library (default)\n"
"\t--disable-static Do not compile static library\n"
"\n"
"\t--xmemory-mode=M M=0 switches off the internal xmemory\n"
"\t handling, M=1 exits the program\n"
"\t whenever a memory allocation fails,\n"
"\t M=2 switches on the internal xmemory\n"
"\t handling.\n"
"\n"
"\t--max-ptrs=MAXPTRS Set MAXPTRS as the maximum number of\n"
"\t pointers allowed\n"
"\n"
"\t--prefix=PATH Install in PATH (must be absolute)\n"
"\t--mt Compile with multithreading support\n"
"\n"
"options specific to compilation with gcc (for developers):\n"
"\t--lint Compile with -Wall\n"
"\n"
"If your platform is not or incorrectly recognized, you\n"
"can force a given configuration with this option:\n"
"\n"
"\t--os=NAME Where NAME is one of the following:\n"
"\n"
"\tlinux - Linux systems (any processor type)\n"
"\tcygwin - Cygwin (UNIX environment for Windows)\n"
"\thp08 - HPUX version 8.x\n"
"\thp09 - HPUX version 9.x\n"
"\thp10 - HPUX version 10.x\n"
"\thp11 - HPUX version 11.x\n"
"\tirix - SGI IRIX64\n"
"\taix - IBM AIX (any version)\n"
"\tdec - Dec OSF/1 or Tru64 Unix\n"
"\tsolaris - Sun Solaris >=2.5\n"
"\tbsd - BSD compatible Unix\n"
"\tdarwin - Darwin (BSD compatible on Mac)\n" "\n");
}
int
main (argc, argv)
int argc;
char *argv[];
{
char sysname[MAXSTRSZ];
char *sval;
int i;
config.debug_compile = 0;
config.lint_compile = 0;
config.compiler = COMPILER_AUTO;
config.with_threads = 0;
config.lib_static = 1;
config.lib_dynamic = 0;
config.prefix = NULL;
config.max_ptrs = -1;
config.xmemory_mode = -1;
memset (config.sysname, 0, MAXSTRSZ);
memset (config.release, 0, MAXSTRSZ);
memset (config.machine, 0, MAXSTRSZ);
for (i = 0; i < argc; i++)
{
if (!strcmp (argv[i], "--help"))
{
help ();
return 1;
}
else if (!strcmp (argv[i], "--debug"))
{
config.debug_compile = 1;
}
else if (!strcmp (argv[i], "--with-cc"))
{
config.compiler = COMPILER_CC;
}
else if (!strcmp (argv[i], "--with-gcc"))
{
config.compiler = COMPILER_GCC;
}
else if (!strcmp (argv[i], "--lint"))
{
config.lint_compile = 1;
}
else if (!strcmp (argv[i], "--mt"))
{
config.with_threads = 1;
}
else if (!strcmp (argv[i], "--enable-shared"))
{
config.lib_dynamic = 1;
}
else if (!strcmp (argv[i], "--disable-shared"))
{
config.lib_dynamic = 0;
}
else if (!strcmp (argv[i], "--enable-static"))
{
config.lib_static = 1;
}
else if (!strcmp (argv[i], "--disable-static"))
{
config.lib_static = 0;
}
else if (!strncmp (argv[i], "--prefix=", 9))
{
config.prefix = strchr (argv[i], '=') + 1;
}
else if (!strncmp (argv[i], "--max-ptrs=", 11))
{
sval = strchr (argv[i], '=') + 1;
config.max_ptrs = (int) atoi (sval);
}
else if (!strncmp (argv[i], "--xmemory-mode=", 15))
{
sval = strchr (argv[i], '=') + 1;
config.xmemory_mode = (int) atoi (sval);
}
else if (!strncmp (argv[i], "--os=", 5))
{
strcpy (sysname, argv[i] + 5);
if (!strcmp (sysname, "linux"))
{
strcpy (config.sysname, "Linux");
}
else if (!strcmp (sysname, "cygwin"))
{
strcpy (config.sysname, "CYGWIN");
}
else if (!strcmp (sysname, "hp08"))
{
strcpy (config.sysname, "HPUX");
strcpy (config.release, "8.x");
}
else if (!strcmp (sysname, "hp09"))
{
strcpy (config.sysname, "HPUX");
strcpy (config.release, "9.x");
}
else if (!strcmp (sysname, "hp10"))
{
strcpy (config.sysname, "HPUX");
strcpy (config.release, "10.x");
}
else if (!strcmp (sysname, "hp11"))
{
strcpy (config.sysname, "HPUX");
strcpy (config.release, "11.x");
}
else if (!strcmp (sysname, "irix"))
{
strcpy (config.sysname, "IRIX64");
}
else if (!strcmp (sysname, "aix"))
{
strcpy (config.sysname, "AIX");
}
else if (!strcmp (sysname, "dec"))
{
strcpy (config.sysname, "Dec OSF/1 or Tru64");
}
else if (!strcmp (sysname, "solaris"))
{
strcpy (config.sysname, "Solaris");
strcpy (config.release, ">= 2.5");
}
else if (!strcmp (sysname, "bsd"))
{
strcpy (config.sysname, "BSD compatible");
}
else if (!strcmp (sysname, "darwin"))
{
strcpy (config.sysname, "Darwin");
}
else
{
printf ("unsupported OS: %s\n", sysname);
return -1;
}
}
}
detect_config ();
make_config_make ();
make_config_h ();
return 0;
}