From 76552d595db509d47e9bf179aac7a00e2f1fcfae Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 19 May 2013 19:18:01 +0200 Subject: [PATCH] Add compiler target compile options. For clang, this allows passing -target to the compiler, and for qcc, -V using toolchain files containing something like set(triple arm-linux-gnueabihf) set(CMAKE_C_COMPILER "/usr/bin/clang") set(CMAKE_C_COMPILER_TARGET ${triple}) set(CMAKE_CXX_COMPILER "/usr/bin/clang++") set(CMAKE_CXX_COMPILER_TARGET ${triple}) or set(arch gcc_ntoarmv7le) set(CMAKE_C_COMPILER /opt/qnx650/host/linux/x86/usr/bin/qcc) set(CMAKE_C_COMPILER_TARGET ${arch}) set(CMAKE_CXX_COMPILER /opt/qnx650/host/linux/x86/usr/bin/QCC) set(CMAKE_CXX_COMPILER_TARGET ${arch}) Both clang and qcc are inherently cross compiler( driver)s. When cross-compiling with clang, use the CMAKE_${lang}_COMPILER_TARGET as the _CMAKE_TOOLCHAIN_PREFIX to find the appropriate binutils. When cross-compiling with QNX qcc, use the CMAKE_${lang}_COMPILER_TARGET to set the appropriate _CMAKE_TOOLCHAIN_PREFIX. --- Help/manual/cmake-variables.7.rst | 1 + Help/variable/CMAKE_LANG_COMPILER_TARGET.rst | 11 +++++++++++ Modules/CMakeDetermineCCompiler.cmake | 6 ++++++ Modules/CMakeDetermineCXXCompiler.cmake | 6 ++++++ Modules/Compiler/Clang.cmake | 1 + Modules/Platform/QNX.cmake | 3 +++ Source/cmCoreTryCompile.cxx | 14 ++++++++++++++ Source/cmLocalGenerator.cxx | 15 +++++++++++++++ 8 files changed, 57 insertions(+) create mode 100644 Help/variable/CMAKE_LANG_COMPILER_TARGET.rst diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 59e806443..c2af59601 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -234,6 +234,7 @@ Variables for Languages /variable/CMAKE_LANG_COMPILER_ID /variable/CMAKE_LANG_COMPILER_LOADED /variable/CMAKE_LANG_COMPILER + /variable/CMAKE_LANG_COMPILER_TARGET /variable/CMAKE_LANG_COMPILER_VERSION /variable/CMAKE_LANG_CREATE_SHARED_LIBRARY /variable/CMAKE_LANG_CREATE_SHARED_MODULE diff --git a/Help/variable/CMAKE_LANG_COMPILER_TARGET.rst b/Help/variable/CMAKE_LANG_COMPILER_TARGET.rst new file mode 100644 index 000000000..7c8efee9b --- /dev/null +++ b/Help/variable/CMAKE_LANG_COMPILER_TARGET.rst @@ -0,0 +1,11 @@ +CMAKE__COMPILER_TARGET +---------------------------- + +The target for cross-compiling, if supported. + +Some compiler drivers are inherently cross-compilers, such as clang and +QNX qcc. These compiler drivers support a command-line argument to specify +the target to cross-compile for. + +This variable may only be set in a toolchain file specified by +the ``CMAKE_TOOLCHAIN_FILE`` variable. diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake index 0d47a60a9..438a98a5d 100644 --- a/Modules/CMakeDetermineCCompiler.cmake +++ b/Modules/CMakeDetermineCCompiler.cmake @@ -158,6 +158,12 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME) if (COMPILER_BASENAME MATCHES "^(.+-)(clang|g?cc)(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$") set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) + elseif("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_C_COMPILER_TARGET}-) + elseif(COMPILER_BASENAME MATCHES "qcc(\\.exe)?$") + if(CMAKE_C_COMPILER_TARGET MATCHES "gcc_nto([^_le]+)(le)?.*$") + set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-) + endif() endif () # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake index e88218922..5f9d9bf60 100644 --- a/Modules/CMakeDetermineCXXCompiler.cmake +++ b/Modules/CMakeDetermineCXXCompiler.cmake @@ -156,6 +156,12 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME) if (COMPILER_BASENAME MATCHES "^(.+-)(clan)?[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$") set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) + elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_CXX_COMPILER_TARGET}-) + elseif(COMPILER_BASENAME MATCHES "QCC(\\.exe)?$") + if(CMAKE_CXX_COMPILER_TARGET MATCHES "gcc_nto([^_le]+)(le)?.*$") + set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-) + endif() endif () # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index 7d7be5c4b..f0ea2f802 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -30,5 +30,6 @@ else() set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") + set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-target ") endmacro() endif() diff --git a/Modules/Platform/QNX.cmake b/Modules/Platform/QNX.cmake index 068799f91..9afde0557 100644 --- a/Modules/Platform/QNX.cmake +++ b/Modules/Platform/QNX.cmake @@ -16,6 +16,9 @@ set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,") set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,") set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic") +# http://www.qnx.com/developers/docs/6.4.0/neutrino/utilities/q/qcc.html#examples +set(CMAKE_C_COMPILE_OPTIONS_TARGET "-V") +set(CMAKE_CXX_COMPILE_OPTIONS_TARGET "-V") # Shared libraries with no builtin soname may not be linked safely by # specifying the file path. diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 479a6995c..5bf8ce58b 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -405,6 +405,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector const& argv) flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_DEPLOYMENT_TARGET"); cmakeFlags.push_back(flag); } + if (const char *cxxDef + = this->Makefile->GetDefinition("CMAKE_CXX_COMPILER_TARGET")) + { + std::string flag="-DCMAKE_CXX_COMPILER_TARGET="; + flag += cxxDef; + cmakeFlags.push_back(flag); + } + if (const char *cDef + = this->Makefile->GetDefinition("CMAKE_C_COMPILER_TARGET")) + { + std::string flag="-DCMAKE_C_COMPILER_TARGET="; + flag += cDef; + cmakeFlags.push_back(flag); + } if(this->Makefile->GetDefinition("CMAKE_POSITION_INDEPENDENT_CODE")!=0) { fprintf(fout, "set(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n"); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 63ec576d8..c308ba85c 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1043,11 +1043,20 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, // If this is the compiler then look for the extra variable // _COMPILER_ARG1 which must be the first argument to the compiler const char* compilerArg1 = 0; + const char* compilerTarget = 0; + const char* compilerOptionTarget = 0; if(actualReplace == "CMAKE_${LANG}_COMPILER") { std::string arg1 = actualReplace + "_ARG1"; cmSystemTools::ReplaceString(arg1, "${LANG}", lang); compilerArg1 = this->Makefile->GetDefinition(arg1.c_str()); + compilerTarget + = this->Makefile->GetDefinition( + (std::string("CMAKE_") + lang + "_COMPILER_TARGET").c_str()); + compilerOptionTarget + = this->Makefile->GetDefinition( + (std::string("CMAKE_") + lang + + "_COMPILE_OPTIONS_TARGET").c_str()); } if(actualReplace.find("${LANG}") != actualReplace.npos) { @@ -1068,6 +1077,12 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, ret += " "; ret += compilerArg1; } + if (compilerTarget && compilerOptionTarget) + { + ret += " "; + ret += compilerOptionTarget; + ret += compilerTarget; + } return ret; } return replace;