Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

g++, colorgcc and ccache

Tags:

Trying to combine ccache and colorgcc. Following link text:

  • my g++ is soft link to colorgcc
  • ~/.colorgccrc contains line: "g++: ccache /usr/bin/g++"

When running g++ --version receive:

Can't exec "ccache  /usr/bin/gcc": No such file or directory at /usr/lib/perl5/5.8.8/IPC/Open3.pm line 246. open3: exec of ccache  /usr/bin/gcc --version failed at /usr/local/bin/colorgcc/gcc line 208 

Any ideas how to solve it?

like image 856
dimba Avatar asked Jan 03 '10 16:01

dimba


2 Answers

Just came across this same issue. For me, the problem could be solved by carefully setting environment variables:

# Make "g++" command call colorgcc export PATH="/usr/lib/colorgcc/bin:$PATH"  # Tell ccache to invoke compilers in /usr/bin export CCACHE_PATH="/usr/bin" 

Then all I had to do was edit colorgcc's config file (/etc/colorgcc/colorgcc or ~/.colorgcc) and tell it to call ccache instead:

g++: /usr/lib/ccache/bin/g++ gcc: /usr/lib/ccache/bin/gcc c++: /usr/lib/ccache/bin/g++ cc:  /usr/lib/ccache/bin/gcc g77: /usr/lib/ccache/bin/g77 f77: /usr/lib/ccache/bin/g77 gcj: /usr/lib/ccache/bin/gcj 

This of course only works if you have colorgcc's symlinks installed in /usr/lib/colorgcc/bin and ccache's symlinks in /usr/lib/ccache/bin - adjust accordingly.

like image 163
Malvineous Avatar answered Oct 05 '22 22:10

Malvineous


The Short Answer

Without patching colorgcc.pl itself, the easiest way to fix this is to write yourself a simple wrapper script for each command, calling ccache with the appropriate arguments for that command, and passing along the arguments the script received (effectively currying the call to ccache.)

E.g., for gcc:

  • /usr/local/bin/ccache-gcc.sh:

    #!/bin/bash ccache /usr/bin/gcc "$@" 
  • ~/.colorgcc:

    gcc: /usr/local/bin/ccache-gcc.sh 

and for g++:

  • /usr/local/bin/ccache-g++.sh:

    #!/bin/bash ccache /usr/bin/g++ "$@" 
  • ~/.colorgcc:

    gcc: /usr/local/bin/ccache-g++.sh 

There are ways to clean this up so that you only use a single script, with symlinks for each variant, but those are beyond the scope of this answer, and I leave them to you as an excercise :-)

The Long Answer

The problem is that the script treats everything to the right of the colon in the prefs file as the "command" passed to exec, not as the "command" and extra "arguments". I.e., in your case, the script ends up trying to do this:

  • Incorrect:

    exec "ccache /usr/bin/g++" "--version" 

    (i.e., "ccache /usr/bin/g++" is a single argument.)

But it should be doing this:

  • Correct:

    exec "ccache" "/usr/bin/g++" "--version" 

    (i.e., "ccache" and "/usr/bin/g++" are two separate arguments.)

Perl's exec ultimately calls execvp, after possibly applying some "do what I mean" logic to its arguments. execvp then does some DWIM of its own. Perl's exec pre-processing, which splits up a single argument string into the multiple arguments execvp expects, only kicks in when exec receives a single argument. In colorgcc.pl, the call to exec looks like this (roughly):

exec "${program}" @ARGV 

where ${program} comes from your configuration (or the defaults), and @ARGV is the list of arguments you passed when you (indirectly) invoked colorgcc.pl. In your case, ${program} is, literally, ccache /usr/bin/g++ (a single string, as noted above,) when it ought to be just ccache, with /usr/bin/g++ being prepended to @ARGV.


(Some of you may wonder why I've gone to all the trouble of explaining this, when it's a one-line fix to colorgcc.pl. That's true, but if I just did that, the world would lose another opportunity to learn about this class of errors. Plus, I wouldn't get as many votes.)

like image 28
Tripp Lilley Avatar answered Oct 05 '22 23:10

Tripp Lilley