/*--------------------------------------------------------------------------- File name : sysconf.c Author : Nicolas Devillard Created on : February 2001 Description : configure-like in C. ---------------------------------------------------------------------------*/ /* $Id: sysconf.c,v 1.17 2002/01/22 14:47:55 ndevilla Exp $ $Author: ndevilla $ $Date: 2002/01/22 14:47:55 $ $Revision: 1.17 $ */ /*--------------------------------------------------------------------------- Includes ---------------------------------------------------------------------------*/ #include #include #include #include #include #include #define MAXSTRSZ 512 #define MACROS_FILE "config.make" #define HEADER_FILE "config.h" #define PREFIX_DEFAULT "/opt/qfits" #define COMPILER_AUTO 0 #define COMPILER_CC 1 #define COMPILER_GCC 2 /* Global variable */ struct { /* List of supported OS's */ enum { os_linux, os_hp08, os_hp09, os_hp10, os_hp11, os_solaris, 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 tracing (gcc only >= 2.95) */ int with_trace ; /* Compile with threads */ int with_threads ; /* Number of detected CPUs */ int ncpus ; /* Compile with gcc3 (pollux only) */ int gcc3 ; /* Compile static library */ int lib_static ; /* Compile dynamic library */ int lib_dynamic ; /* Prefix for installation */ char * prefix ; } config ; /* Guess local OS name and potentially release number */ 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, "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, "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 ; } 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) { /* Linux and BSD use gcc always */ case os_linux: case os_bsd: 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 = "); 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\n"); } 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\n"); } 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\n"); } 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\n"); } else { fprintf(sysc, "-O\n"); } fprintf(sysc, "RELOC =\n"); fprintf(sysc, "SHARED = -shared -expect_unresolved \"*\"\n"); break ; 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\n"); } else { fprintf(sysc, "-O\n"); } fprintf(sysc, "RELOC =\n"); fprintf(sysc, "SHARED =\n"); break ; case os_linux: /* cc with Linux? Why not! */ if (config.with_threads) { fprintf(sysc, "-pthread "); } if (config.debug_compile) { fprintf(sysc, "-g\n"); } 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' */ fprintf(sysc, "-DOS_DARWIN=1 -Dsrand48=srandom -Ddrand48=random "); if (config.with_threads) { fprintf(sysc, "-pthread "); } if (config.debug_compile) { fprintf(sysc, "-g\n"); } 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: if (config.gcc3) { fprintf(sysc, "CC = /opt/gcc3/bin/gcc\n"); } else { fprintf(sysc, "CC = gcc\n"); } fprintf(sysc, "CFLAGS = "); if (config.with_threads) { fprintf(sysc, "-pthread "); } if (config.lint_compile) { fprintf(sysc, " -Wall -pedantic "); } if (config.debug_compile) { fprintf(sysc, "-g\n"); } else { fprintf(sysc, "-O3\n"); } if (config.with_trace) { fprintf(sysc, "FTRACE = -finstrument-functions\n"); } else { fprintf(sysc, "FTRACE =\n"); } fprintf(sysc, "RELOC = -fpic\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"); } if (config.with_trace) { printf(" with function tracing\n"); } /* LFLAGS */ switch (config.local_os) { case os_hp10: case os_hp11: fprintf(sysc, "# Shut up HPUX 11 linker\n"); fprintf(sysc, "LFLAGS = -Wl,+vnocompatwarnings\n"); break ; default: fprintf(sysc, "LFLAGS =\n"); break ; } /* RANLIB */ switch (config.local_os) { case os_hp08: case os_hp09: case os_hp10: case os_hp11: fprintf(sysc, "RANLIB = ranlib\n"); fprintf(sysc, "DYNSUF = sl\n"); break ; case os_darwin: fprintf(sysc, "RANLIB = ranlib\n"); fprintf(sysc, "DYNSUF = so\n"); break ; default: fprintf(sysc, "RANLIB = true\n"); 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); } 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\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_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 ; } 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--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" "\t--trace Compile function tracing capabilities\n" "\t--gcc3 Compile with gcc3 in /opt/gcc3\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" "\thp08 - HPUX version 8.x\n" "\thp09 - HPUX version 9.x\n" "\thp10 - HPUX version 10.x\n" "\thp11 - HPUX version 11.x\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]; int i ; config.debug_compile = 0; config.lint_compile = 0 ; config.compiler = COMPILER_AUTO ; config.with_threads = 0 ; config.with_trace = 0 ; config.gcc3 = 0 ; config.lib_static = 1 ; config.lib_dynamic = 0 ; config.prefix = NULL ; memset(config.sysname, 0, MAXSTRSZ); memset(config.release, 0, MAXSTRSZ); memset(config.machine, 0, MAXSTRSZ); for (i=0 ; i= 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 ; }