#include #include #include #include #include FILE *fOut = NULL; bool bHasDevNull; bool testCpp( const char *prog ) { FILE *pop = popen( bHasDevNull?"g++ -x c++ - -o /dev/null":"g++ -x c++ - -o trash.del", "w"); fwrite( prog, 1, strlen( prog ), pop ); bool bFound = (pclose(pop) == 0); if( !bHasDevNull ) unlink("trash.del"); return bFound; } bool testLib( const char *lib, const char *symname, const char *humname ) { printf("Detecting library %s (-l%s)...", humname, lib ); fflush( stdout ); static const char *prog = "int main () { return 0; }"; char *cmdline = (char *)malloc( 29+strlen(lib) ); strcpy( cmdline, "g++ -x c++ -l"); strcat( cmdline, lib ); if( bHasDevNull ) strcat( cmdline, " - -o /dev/null"); else strcat( cmdline, " - -o trash.del"); FILE *pop = popen( cmdline, "w"); fwrite( prog, 1, strlen( prog ), pop ); free( cmdline ); bool bFound = (pclose(pop) == 0); if( bFound ) { printf("found.\n"); fprintf( fOut, "#define BU_FEATURE_%s 1\n", symname ); fprintf( fOut, "#define BU_HAS_%s\n", symname ); } else { printf("missing.\n"); fprintf( fOut, "#define BU_FEATURE_%s 0\n", symname ); fprintf( fOut, "#define BU_MISSING_%s\n", symname ); } if( !bHasDevNull ) unlink("trash.del"); return bFound; } void detectEndianness() { printf("Detecting endian support..."); fflush( stdout ); if( testCpp("#include \n\nint main() { return BYTE_ORDER; }\n") ) { fprintf( fOut, "#include \n\n"); printf("header file endian.h found, using that.\n"); } else { uint16_t x=0x0100; fprintf( fOut, "#define LITTLE_ENDIAN 0\n" "#define BIG_ENDIAN 1\n" "#define BYTE_ORDER %d\n\n", ((uint8_t *)&x)[0] ); printf("no header file found, faking it...\n" "\tArchetecture is: %s Endian\n", ((uint8_t *)&x)[0]?"Big":"Little" ); } } bool fileExists( const char *filename ) { FILE *fTmp = fopen(filename, "rw"); if( fTmp == NULL ) return false; fclose( fTmp ); return true; } int main( int argc, char *argv[] ) { if( argc == 1 ) { fprintf( stderr, "Invalid usage: specify a file to generate:\n" " src/autoconfig.h\n" " src/version.h\n" "\n" ); return 127; } bHasDevNull = fileExists("/dev/null"); if( strcmp( argv[1], "src/autoconfig.h" ) == 0 ) { fOut = fopen( argv[1], "w" ); fprintf( fOut, "#ifndef BU_AUTO_CONFIG_H\n" "#define BU_AUTO_CONFIG_H\n\n" ); detectEndianness(); testLib("z", "DEFLATE", "Deflate"); testLib("bz2", "BZIP2", "BZip2"); testLib("lzma", "LZMA", "Lzma"); fprintf( fOut, "#endif\n"); } else if( strcmp( argv[1], "src/version.h" ) == 0 ) { FILE *fVer = fopen("version", "rt"); char buf[1024]; buf[fread( buf, 1, 1024, fVer )] = '\0'; for( int j = 0; buf[j]; j++ ) if( buf[j] == '\n' ) buf[j] = '\0'; fclose( fVer ); char *end; int32_t iVer = strtol( buf, &end, 10 ); for(; (*end < '1' || *end > '9') && *end; end++ ) { } int32_t iRev = strtol( end, NULL, 10 ); fOut = fopen( argv[1], "w" ); fprintf( fOut, "#ifndef BU_VERSION_H\n" "#define BU_VERSION_H\n\n" "#define LIBBU_VERSION %d\n" "#define LIBBU_REVISION %d\n" "#define LIBBU_VERSION_STR \"%s\"\n" "#define LIBBU_API 0\n" "#define LIBBU_VC_ID \"", iVer, iRev, buf ); FILE *psub = popen("git describe --always", "r"); buf[fread( buf, 1, 1024, psub )] = '\0'; for( int j = 0; buf[j]; j++ ) { if( buf[j] == '\n' ) { buf[j] = '\0'; } } fwrite( buf, strlen(buf), 1, fOut ); pclose( psub ); fprintf( fOut, "\"\n\n#endif\n"); } return 0; }