SVN commit 1304627 by lunakl: use the given compiler type and not always gcc Send the compiler name to the remote, so that it knows whether it has to use gcc or clang. Currently clang compilations will fail if the remote CS is older version than this. M +8 -2 daemon/environment.cpp M +2 -2 daemon/serve.cpp M +16 -2 daemon/workit.cpp M +19 -0 services/comm.cpp M +3 -1 services/comm.h --- trunk/icecream/daemon/environment.cpp #1304626:1304627 @@ -136,7 +136,7 @@ for ( struct dirent *ent = readdir(envdir); ent; ent = readdir( envdir ) ) { string dirname = ent->d_name; - if ( !access( string( targetdir + "/" + dirname + "/usr/bin/gcc" ).c_str(), X_OK ) ) + if ( !access( string( targetdir + "/" + dirname + "/usr/bin/as" ).c_str(), X_OK ) ) envs.push_back( make_pair( current_target, dirname ) ); } closedir( envdir ); @@ -214,7 +214,13 @@ native_environment = ""; string nativedir = basedir + "/native/"; - if ( ::access( "/usr/bin/gcc", X_OK ) || ::access( "/usr/bin/g++", X_OK ) ) + // 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 ) return 0; if ( mkdir( nativedir.c_str(), 0775 ) ) --- trunk/icecream/daemon/serve.cpp #1304626:1304627 @@ -113,8 +113,8 @@ try { if ( job->environmentVersion().size() ) { string dirname = basedir + "/target=" + job->targetPlatform() + "/" + job->environmentVersion(); - if ( ::access( string( dirname + "/usr/bin/gcc" ).c_str(), X_OK ) ) { - error_client( client, dirname + "/usr/bin/gcc is not executable" ); + if ( ::access( string( dirname + "/usr/bin/as" ).c_str(), X_OK ) ) { + error_client( client, dirname + "/usr/bin/as is not executable" ); log_error() << "I don't have environment " << job->environmentVersion() << "(" << job->targetPlatform() << ") " << job->jobID() << endl; throw myexception( EXIT_DISTCC_FAILED ); // the scheduler didn't listen to us! } --- trunk/icecream/daemon/workit.cpp #1304626:1304627 @@ -178,15 +178,26 @@ argc += 6; // -x c - -o file.o -fpreprocessed argc += 4; // gpc parameters argc += 1; // -pipe + argc += 1; // -no-canonical-prefixes char **argv = new char*[argc + 1]; int i = 0; + bool clang = false; + if (IS_PROTOCOL_30( client )) { + assert(!j.compilerName().empty()); + clang = (j.compilerName().find( "clang" ) != string::npos); + argv[i++] = strdup(( "usr/bin/" + j.compilerName()).c_str()); + } else { if (j.language() == CompileJob::Lang_C) argv[i++] = strdup( "usr/bin/gcc" ); else if (j.language() == CompileJob::Lang_CXX) argv[i++] = strdup( "usr/bin/g++" ); else assert(0); + } + argv[i++] = strdup("-x"); + argv[i++] = strdup((j.language() == CompileJob::Lang_CXX) ? "c++" : "c"); + bool hasPipe = false; for ( std::list::const_iterator it = list.begin(); it != list.end(); ++it) { @@ -194,20 +205,23 @@ hasPipe = true; argv[i++] = strdup( it->c_str() ); } + if (!clang) argv[i++] = strdup("-fpreprocessed"); if(!hasPipe) argv[i++] = strdup("-pipe"); - argv[i++] = strdup("-x"); - argv[i++] = strdup((j.language() == CompileJob::Lang_CXX) ? "c++" : "c"); argv[i++] = strdup( "-" ); argv[i++] = strdup( "-o" ); argv[i++] = strdup(outfilename.c_str()); + if (!clang) { argv[i++] = strdup( "--param" ); sprintf( buffer, "ggc-min-expand=%d", ggc_min_expand_heuristic( mem_limit ) ); argv[i++] = strdup( buffer ); argv[i++] = strdup( "--param" ); sprintf( buffer, "ggc-min-heapsize=%d", ggc_min_heapsize_heuristic( mem_limit ) ); argv[i++] = strdup( buffer ); + } + if (clang) + argv[i++] = strdup( "-no-canonical-prefixes" ); // otherwise clang tries to access /proc/self/exe // before you add new args, check above for argc argv[i] = 0; assert(i <= argc); --- trunk/icecream/services/comm.cpp #1304626:1304627 @@ -1338,7 +1338,13 @@ string target; *c >> target; job->setTargetPlatform( target ); + if (IS_PROTOCOL_30(c)) + { + string compilerName; + *c >> compilerName; + job->setCompilerName( compilerName ); } +} void CompileFileMsg::send_to_channel (MsgChannel *c) const @@ -1350,8 +1356,21 @@ *c << job->restFlags(); *c << job->environmentVersion(); *c << job->targetPlatform(); + if (IS_PROTOCOL_30(c)) + *c << remote_compiler_name(); } +// Environments created by icecc-create-env always use the same binary name +// for compilers, so even if local name was e.g. c++, remote needs to +// be g++ (before protocol version 30 remote CS even had /usr/bin/{gcc|g++} +// hardcoded). +string CompileFileMsg::remote_compiler_name() const +{ + if (job->compilerName().find("clang") != string::npos) + return job->language() == CompileJob::Lang_CXX ? "clang++" : "clang"; + return job->language() == CompileJob::Lang_CXX ? "g++" : "gcc"; +} + CompileJob * CompileFileMsg::takeJob() { --- trunk/icecream/services/comm.h #1304626:1304627 @@ -35,7 +35,7 @@ #include "job.h" // if you increase the PROTOCOL_VERSION, add a macro below and use that -#define PROTOCOL_VERSION 29 +#define PROTOCOL_VERSION 30 // if you increase the MIN_PROTOCOL_VERSION, comment out macros below and clean up the code #define MIN_PROTOCOL_VERSION 21 @@ -53,6 +53,7 @@ #define IS_PROTOCOL_27( c ) ( (c)->protocol >= 27 ) #define IS_PROTOCOL_28( c ) ( (c)->protocol >= 28 ) #define IS_PROTOCOL_29( c ) ( (c)->protocol >= 29 ) +#define IS_PROTOCOL_30( c ) ( (c)->protocol >= 30 ) enum MsgType { // so far unknown @@ -337,6 +338,7 @@ CompileJob *takeJob(); private: + std::string remote_compiler_name() const; bool deleteit; CompileJob *job; };