SVN commit 1308592 by lunakl: do not create environments containing both gcc and clang Now that there can be more than one native environment, this doesn't make much sense. Bigger environments would more likely fill up cache size on remotes, especially with more environments because of using compiler plugins, leading to environments getting discarded. This commit partially breaks backwards compatibility with previous clang-capable icecream from svn, but not with the last icecream release. M +27 -15 client/icecc-create-env M +40 -30 client/main.cpp M +10 -9 daemon/environment.cpp M +2 -1 daemon/environment.h M +3 -3 daemon/main.cpp M +6 -2 services/comm.cpp M +3 -2 services/comm.h --- trunk/icecream/client/icecc-create-env #1308591:1308592 @@ -13,8 +13,8 @@ usage () { - echo "usage: $0 " - echo "usage: $0 [|] [|] " + echo "usage: $0 --gcc " + echo "usage: $0 --clang " echo "usage: Use --addfile to add extra files." } @@ -83,13 +83,35 @@ shift fi +if test "$1" != "--gcc" -a "$1" != "--clang"; then + # backward compat added_gcc=$1 shift added_gxx=$1 shift + gcc=1 +else + if test "$1" = "--gcc"; then + shift + added_gcc=$1 + shift + added_gxx=$1 + shift + gcc=1 + elif test "$1" = "--clang"; then + shift + added_clang=$1 + shift + added_compilerwrapper=$1 + shift + clang=1 + else + usage + exit 1 + fi +fi -if test -n "$added_gcc" || test -n "$added_gxx"; then - gcc=1 +if test -n "$gcc"; then if test -z "$added_gcc" || test -z "$added_gxx"; then usage exit 1 @@ -104,27 +126,17 @@ fi fi -if test -n "$1" -a "x$1" != "x--addfile"; then - added_clang=$1 - shift - clang=1 +if test -n "$clang"; then if ! test -x "$added_clang" ; then echo "'$added_clang' is no executable." exit 1 fi - added_compilerwrapper=$1 - shift if ! test -x "$added_compilerwrapper" ; then echo "'$added_compilerwrapper' is no executable." exit 1 fi fi -if test -z "$gcc" && test -z "$clang"; then - usage - exit 1 -fi - extrafiles= while test "x$1" = "x--addfile"; do shift --- trunk/icecream/client/main.cpp #1308591:1308592 @@ -70,12 +70,13 @@ printf( "Usage:\n" " icecc [compiler] [compile options] -o OBJECT -c SOURCE\n" +" icecc --build-native [compilertype] [file...]\n" " icecc --help\n" "\n" "Options:\n" " --help explain usage and exit\n" " --version show version and exit\n" -" --build-native [file]... create icecc environment\n" +" --build-native create icecc environment\n" "Environment Variables:\n" " ICECC if set to \"no\", just exec the real gcc\n" " ICECC_VERSION use a specific icecc environment, see icecc-create-env\n" @@ -157,11 +158,43 @@ return output.substr(0, output.length()-1); } -static int create_native( char* extrafiles[] ) +static int create_native( char** args ) { + // args are [compiler] [files...] + const char *compiler = args[ 0 ]; + char **extrafiles; + if( args[ 0 ] ) + extrafiles = args + 1; + else // there were no arguments, set to null list + extrafiles = args; + int extracount = 0; + while ( extrafiles[ extracount ] ) + ++extracount; + char **argv = new char*[4+extracount*2]; + int pos = 0; struct stat st; - string gcc, gpp, clang; + if ( lstat( PLIBDIR "/icecc-create-env", &st ) ) { + log_error() << PLIBDIR "/icecc-create-env does not exist\n"; + return 1; + } + argv[pos++] = strdup( PLIBDIR "/icecc-create-env" ); + if ( strcmp( compiler, "clang" ) == 0 ) { + string clang = compiler_path_lookup( "clang" ); + if ( clang.empty()) { + log_error() << "clang compiler not found\n"; + return 1; + } + if ( lstat( PLIBDIR "/compilerwrapper", &st ) ) { + log_error() << PLIBDIR "/compilerwrapper does not exist\n"; + return 1; + } + argv[pos++] = strdup( "--clang" ); + argv[pos++] = strdup( clang.c_str() ); + argv[pos++] = strdup( PLIBDIR "/compilerwrapper" ); + } else { // "gcc" (default) + string gcc, gpp; + // perhaps we're on gentoo if ( !lstat("/usr/bin/gcc-config", &st) ) { string gccpath=read_output("/usr/bin/gcc-config -B") + "/"; @@ -171,48 +204,25 @@ gcc = compiler_path_lookup( "gcc" ); gpp = compiler_path_lookup( "g++" ); } - - clang = compiler_path_lookup( "clang" ); - // both C and C++ compiler are required if ( gcc.empty()) gpp.clear(); if ( gpp.empty()) gcc.clear(); - - if ( gcc.empty() && gpp.empty() && clang.empty()) + if ( gcc.empty() && gpp.empty()) { + log_error() << "gcc compiler not found\n"; return 1; - - if ( lstat( PLIBDIR "/icecc-create-env", &st ) ) { - log_error() << PLIBDIR "/icecc-create-env does not exist\n"; - return 1; } - - if ( !clang.empty() && lstat( PLIBDIR "/compilerwrapper", &st ) ) { - log_error() << PLIBDIR "/compilerwrapper does not exist\n"; - return 1; - } - - int extracount = 0; - while ( extrafiles[ extracount ] ) - ++extracount; - char **argv = new char*[5+extracount*2]; - int pos = 0; - argv[pos++] = strdup( PLIBDIR "/icecc-create-env" ); + argv[pos++] = strdup( "--gcc" ); argv[pos++] = strdup( gcc.c_str() ); argv[pos++] = strdup( gpp.c_str() ); - if( !clang.empty()) { - argv[pos++] = strdup( clang.c_str() ); - argv[pos++] = strdup( PLIBDIR "/compilerwrapper" ); } for ( extracount = 0; extrafiles[ extracount ]; ++extracount ) { argv[pos++] = strdup( "--addfile" ); argv[pos++] = strdup( extrafiles[ extracount ] ); } argv[pos++] = NULL; - return execv(argv[0], argv); - } int main(int argc, char **argv) @@ -327,7 +337,7 @@ log_warning() << "Local daemon is too old to handle compiler plugins.\n"; local = true; } else { - if ( !local_daemon->send_msg( GetNativeEnvMsg( extrafiles ) ) ) { + if ( !local_daemon->send_msg( GetNativeEnvMsg( compiler_is_clang( job ) ? "clang" : "gcc", extrafiles ) ) ) { log_warning() << "failed to write get native environment\n"; goto do_local_error; } --- trunk/icecream/daemon/environment.cpp #1308591:1308592 @@ -230,19 +230,19 @@ } size_t setup_env_cache(const string &basedir, string &native_environment, uid_t nobody_uid, gid_t nobody_gid, - const list& extrafiles) + const std::string &compiler, const list &extrafiles) { native_environment = ""; string nativedir = basedir + "/native/"; - // Either both gcc and g++ are needed, and/or clang. - bool ok = false; - if ( ::access( "/usr/bin/gcc", X_OK ) == 0 && ::access( "/usr/bin/g++", X_OK ) == 0 ) - ok = true; - if ( ::access( "/usr/bin/clang", X_OK ) == 0 ) - ok = true; - if ( !ok ) + if (compiler == "clang") { + if ( ::access( "/usr/bin/clang", X_OK ) != 0 ) return 0; + } else { // "gcc" (the default) + // Both gcc and g++ are needed in the gcc case. + if ( ::access( "/usr/bin/gcc", X_OK ) != 0 || ::access( "/usr/bin/g++", X_OK ) != 0 ) + return 0; + } if ( mkdir( nativedir.c_str(), 0775 ) && errno != EEXIST ) return 0; @@ -303,10 +303,11 @@ close( pipes[ 1 ] ); const char ** argv; - argv = new const char*[ 3 + extrafiles.size() ]; + argv = new const char*[ 4 + extrafiles.size() ]; int pos = 0; argv[ pos++ ] = BINDIR "/icecc"; argv[ pos++ ] = "--build-native"; + argv[ pos++ ] = strdup( compiler.c_str()); for( list::const_iterator it = extrafiles.begin(); it != extrafiles.end(); ++it ) argv[ pos++ ] = strdup( it->c_str()); --- trunk/icecream/daemon/environment.h #1308591:1308592 @@ -29,7 +29,8 @@ class MsgChannel; extern bool cleanup_cache( const std::string &basedir ); extern size_t setup_env_cache(const std::string &basedir, std::string &native_environment, - uid_t nobody_uid, gid_t nobody_gid, const std::list &extrafiles); + uid_t nobody_uid, gid_t nobody_gid, + const std::string &compiler, const std::list &extrafiles); Environments available_environmnents(const std::string &basename); extern void save_compiler_timestamps(time_t &gcc_bin_timestamp, time_t &gpp_bin_timestamp, time_t &clang_bin_timestamp); bool compilers_uptodate(time_t gcc_bin_timestamp, time_t gpp_bin_timestamp, time_t clang_bin_timestamp); --- trunk/icecream/daemon/main.cpp #1308591:1308592 @@ -914,9 +914,9 @@ { string env_key; map extrafilestimes; + env_key = msg->compiler; for( list::const_iterator it = msg->extrafiles.begin(); it != msg->extrafiles.end(); ++it ) { - if (!env_key.empty()) env_key += ':'; env_key += *it; struct stat st; @@ -941,12 +941,12 @@ } trace() << "get_native_env " << native_environments[ env_key ].name - << ( !env_key.empty() ? " (" + env_key + ")" : "" ) << endl; + << " (" << env_key << ")" << endl; if ( !native_environments[ env_key ].name.length()) { NativeEnvironment& env = native_environments[ env_key ]; // also inserts it size_t installed_size = setup_env_cache( envbasedir, env.name, - nobody_uid, nobody_gid, msg->extrafiles ); + nobody_uid, nobody_gid, msg->compiler, msg->extrafiles ); // we only clean out cache on next target install cache_size += installed_size; trace() << "cache_size = " << cache_size << endl; --- trunk/icecream/services/comm.cpp #1308591:1308592 @@ -1627,17 +1627,21 @@ GetNativeEnvMsg::fill_from_channel (MsgChannel *c) { Msg::fill_from_channel (c); - if (IS_PROTOCOL_32(c)) + if (IS_PROTOCOL_32(c)) { + *c >> compiler; *c >> extrafiles; } +} void GetNativeEnvMsg::send_to_channel (MsgChannel *c) const { Msg::send_to_channel (c); - if (IS_PROTOCOL_32(c)) + if (IS_PROTOCOL_32(c)) { + *c << compiler; *c << extrafiles; } +} void UseNativeEnvMsg::fill_from_channel (MsgChannel *c) --- trunk/icecream/services/comm.h #1308591:1308592 @@ -325,8 +325,9 @@ class GetNativeEnvMsg : public Msg { public: GetNativeEnvMsg () : Msg(M_GET_NATIVE_ENV) {} - GetNativeEnvMsg (const std::list& e) - : Msg(M_GET_NATIVE_ENV), extrafiles(e) {} + GetNativeEnvMsg (const std::string &c, const std::list& e) + : Msg(M_GET_NATIVE_ENV), compiler(c), extrafiles(e) {} + std::string compiler; // "gcc" or "clang" right now std::list extrafiles; virtual void fill_from_channel (MsgChannel * c); virtual void send_to_channel (MsgChannel * c) const;