Add options to launch the compiler through tools like ccache or distcc

Create a <LANG>_COMPILER_LAUNCHER target property (initialized by a
CMAKE_<LANG>_COMPILER_LAUNCHER variable) to specify a compiler launcher
tool.  This will supersede the CMAKE_<LANG>_COMPILER_ARG1 approach to
using such tools.  The old approach set CMAKE_<LANG>_COMPILER to the
launcher tool while the new approach leaves this variable set to the
actual compiler.

Implement this property for Makefile and Ninja generators.  It cannot be
implemented for VS or Xcode generators as the IDE build tools offer no
such hooks.
This commit is contained in:
Bill Hoffman 2015-06-04 15:56:56 -04:00 committed by Brad King
parent d3bb5da929
commit 698f75971b
21 changed files with 119 additions and 0 deletions

View File

@ -177,6 +177,7 @@ Properties on Targets
/prop_tgt/JOB_POOL_COMPILE /prop_tgt/JOB_POOL_COMPILE
/prop_tgt/JOB_POOL_LINK /prop_tgt/JOB_POOL_LINK
/prop_tgt/LABELS /prop_tgt/LABELS
/prop_tgt/LANG_COMPILER_LAUNCHER
/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE /prop_tgt/LANG_INCLUDE_WHAT_YOU_USE
/prop_tgt/LANG_VISIBILITY_PRESET /prop_tgt/LANG_VISIBILITY_PRESET
/prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG /prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG

View File

@ -235,6 +235,7 @@ Variables that Control the Build
/variable/CMAKE_INSTALL_NAME_DIR /variable/CMAKE_INSTALL_NAME_DIR
/variable/CMAKE_INSTALL_RPATH /variable/CMAKE_INSTALL_RPATH
/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH /variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH
/variable/CMAKE_LANG_COMPILER_LAUNCHER
/variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE /variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE
/variable/CMAKE_LANG_VISIBILITY_PRESET /variable/CMAKE_LANG_VISIBILITY_PRESET
/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY /variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY

View File

@ -0,0 +1,13 @@
<LANG>_COMPILER_LAUNCHER
------------------------
This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``.
Specify a :ref:`;-list <CMake Language Lists>` containing a command line
for a compiler launching tool. The :ref:`Makefile Generators` and the
:generator:`Ninja` generator will run this tool and pass the compiler and
its arguments to the tool. Some example tools are distcc and ccache.
This property is initialized by the value of
the :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable if it is set
when a target is created.

View File

@ -0,0 +1,8 @@
compiler-launcher
-----------------
* The :ref:`Makefile Generators` and the :generator:`Ninja` generator
learned to add compiler launcher tools like distcc and ccache along with the
compiler for ``C`` and ``CXX`` languages. See the
:variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable and
:prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property for details.

View File

@ -0,0 +1,6 @@
CMAKE_<LANG>_COMPILER_LAUNCHER
------------------------------
Default value for :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property.
This variable is used to initialize the property on each target as it is
created. This is done only when ``<LANG>`` is ``C`` or ``CXX``.

View File

@ -775,6 +775,25 @@ cmMakefileTargetGenerator
} }
} }
// Maybe insert a compiler launcher like ccache or distcc
if (!compileCommands.empty() && (lang == "C" || lang == "CXX"))
{
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
const char *clauncher = this->Target->GetProperty(clauncher_prop);
if (clauncher && *clauncher)
{
std::vector<std::string> launcher_cmd;
cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true);
for (std::vector<std::string>::iterator i = launcher_cmd.begin(),
e = launcher_cmd.end(); i != e; ++i)
{
*i = this->LocalGenerator->EscapeForShell(*i);
}
std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " ";
compileCommands.front().insert(0, run_launcher);
}
}
// Expand placeholders in the commands. // Expand placeholders in the commands.
for(std::vector<std::string>::iterator i = compileCommands.begin(); for(std::vector<std::string>::iterator i = compileCommands.begin();
i != compileCommands.end(); ++i) i != compileCommands.end(); ++i)

View File

@ -22,6 +22,7 @@
#include "cmComputeLinkInformation.h" #include "cmComputeLinkInformation.h"
#include "cmSourceFile.h" #include "cmSourceFile.h"
#include "cmCustomCommandGenerator.h" #include "cmCustomCommandGenerator.h"
#include "cmAlgorithms.h"
#include <algorithm> #include <algorithm>
@ -475,6 +476,25 @@ cmNinjaTargetGenerator
} }
} }
// Maybe insert a compiler launcher like ccache or distcc
if (!compileCmds.empty() && (lang == "C" || lang == "CXX"))
{
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
const char *clauncher = this->Target->GetProperty(clauncher_prop);
if (clauncher && *clauncher)
{
std::vector<std::string> launcher_cmd;
cmSystemTools::ExpandListArgument(clauncher, launcher_cmd, true);
for (std::vector<std::string>::iterator i = launcher_cmd.begin(),
e = launcher_cmd.end(); i != e; ++i)
{
*i = this->LocalGenerator->EscapeForShell(*i);
}
std::string const& run_launcher = cmJoin(launcher_cmd, " ") + " ";
compileCmds.front().insert(0, run_launcher);
}
}
if (!compileCmds.empty()) if (!compileCmds.empty())
{ {
compileCmds.front().insert(0, cldeps); compileCmds.front().insert(0, cldeps);

View File

@ -333,10 +333,12 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->SetPropertyDefault("MACOSX_BUNDLE", 0); this->SetPropertyDefault("MACOSX_BUNDLE", 0);
this->SetPropertyDefault("MACOSX_RPATH", 0); this->SetPropertyDefault("MACOSX_RPATH", 0);
this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0); this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
this->SetPropertyDefault("C_COMPILER_LAUNCHER", 0);
this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", 0); this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", 0);
this->SetPropertyDefault("C_STANDARD", 0); this->SetPropertyDefault("C_STANDARD", 0);
this->SetPropertyDefault("C_STANDARD_REQUIRED", 0); this->SetPropertyDefault("C_STANDARD_REQUIRED", 0);
this->SetPropertyDefault("C_EXTENSIONS", 0); this->SetPropertyDefault("C_EXTENSIONS", 0);
this->SetPropertyDefault("CXX_COMPILER_LAUNCHER", 0);
this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", 0); this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", 0);
this->SetPropertyDefault("CXX_STANDARD", 0); this->SetPropertyDefault("CXX_STANDARD", 0);
this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0); this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0);

View File

@ -232,4 +232,5 @@ endif()
if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
add_executable(pseudo_iwyu pseudo_iwyu.c) add_executable(pseudo_iwyu pseudo_iwyu.c)
add_RunCMake_test(IncludeWhatYouUse -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>) add_RunCMake_test(IncludeWhatYouUse -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>)
add_RunCMake_test(CompilerLauncher)
endif() endif()

View File

@ -0,0 +1 @@
.*-E env USED_LAUNCHER=1.*

View File

@ -0,0 +1 @@
.*-E env USED_LAUNCHER=1.*

View File

@ -0,0 +1,3 @@
set(CTEST_USE_LAUNCHERS 1)
include(CTestUseLaunchers)
include(C.cmake)

View File

@ -0,0 +1,4 @@
enable_language(C)
set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
set(CMAKE_VERBOSE_MAKEFILE TRUE)
add_executable(main main.c)

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.2)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1 @@
.*-E env USED_LAUNCHER=1.*

View File

@ -0,0 +1 @@
.*-E env USED_LAUNCHER=1.*

View File

@ -0,0 +1,3 @@
set(CTEST_USE_LAUNCHERS 1)
include(CTestUseLaunchers)
include(CXX.cmake)

View File

@ -0,0 +1,4 @@
enable_language(CXX)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
set(CMAKE_VERBOSE_MAKEFILE TRUE)
add_executable(main main.cxx)

View File

@ -0,0 +1,23 @@
include(RunCMake)
function(run_compiler_launcher lang)
# Use a single build tree for tests without cleaning.
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${lang}-build)
set(RunCMake_TEST_NO_CLEAN 1)
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
run_cmake(${lang})
set(RunCMake_TEST_OUTPUT_MERGE 1)
if("${RunCMake_GENERATOR}" STREQUAL "Ninja")
set(verbose_args -- -v)
endif()
run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
endfunction()
run_compiler_launcher(C)
run_compiler_launcher(CXX)
if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
run_compiler_launcher(C-launch)
run_compiler_launcher(CXX-launch)
endif()

View File

@ -0,0 +1,3 @@
int main(void) {
return 0;
}

View File

@ -0,0 +1 @@
int main() { return 0; }