From 32a6ab1f3b23b816881d02cca29afcec280408d4 Mon Sep 17 00:00:00 2001 From: Stephen Kelly <stephen.kelly@energid.com> Date: Fri, 24 Jan 2020 16:18:39 +0000 Subject: QNX: Add support for CMAKE_SYSROOT QCC is a wrapper around GCC, but it is not a fully transparent wrapper. Some compile options need to be passed to GCC using a `-Wc` option. QCC does not support --sysroot, so setting CMAKE_SYSROOT in a toolchain file currently does not work. This means that it is likely that no one is setting CMAKE_SYSROOT in existing QNC toolchain files. Override the GCC option for sysroot in the QCC.cmake file with -Wc,-isysroot. This exposes a further issue in that the QNX SDK does not follow the same architectural folder structure as linux uses. That is, on linux systems, architecture-specific libraries might be in <sysroot>/usr/lib/<arch> such as /usr/lib/x86_64-linux-gnu/libcurl.so CMake models this by suffixing the <arch> onto lib directories when searching for libraries. The QNX SDK is structured differently such that the <arch> should be used as a prefix: <sysroot>/<arch>/usr/lib such as <sysroot>/x86_64/usr/lib/libcurl.so Add a variable for platform configuration to set whether to prefix or suffix the <arch> and set that in the QCC.cmake. Use the directory structure of the QNX SDK to compute the <arch> from the implicit library directories. The assumption is that the arch will be a single directory directly below the CMAKE_SYSROOT, below which the usr/ prefix occurs. It would not be appropriate to instruct users to make the <arch> part of the sysroot when specified in the toolchain file because: 1. That would be non-DRY - The QCC wrapper already determines the <arch> by the -V argument passed to the compiler, specified in the toolchain file as the CMAKE_C_COMPILER_TARGET variable. 2. The includes in the QNX SDK are not below the <arch> directory. So, the location of the <arch> in the full path is different on QNX compared to, say an embedded linux platform, but the intent is the same. Add documentation to recommend the use of CMAKE_SYSROOT in a QNX toolchain file. As the CMAKE_SYSROOT is always the same for QNX, it would be possible to simply set it in QCC.cmake. However, that would change behavior for existing users as when CMAKE_SYSROOT is set, files/paths outside of the CMAKE_SYSROOT do not get found. The <arch> prefixing is only enabled in cmSearchPath.cxx if CMAKE_SYSROOT is set. This ensures that the user gets consistency in the current state without CMAKE_SYSROOT, and gets better consistency when using CMAKE_SYSROOT. --- Help/manual/cmake-toolchains.7.rst | 3 +++ Modules/CMakeDetermineCompilerABI.cmake | 12 ++++++++++++ Modules/Compiler/QCC.cmake | 3 +++ Source/cmSearchPath.cxx | 8 +++++++- 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst index f233d08..e8badd4 100644 --- a/Help/manual/cmake-toolchains.7.rst +++ b/Help/manual/cmake-toolchains.7.rst @@ -233,6 +233,9 @@ value to those supported compilers when compiling: set(CMAKE_CXX_COMPILER QCC) set(CMAKE_CXX_COMPILER_TARGET ${arch}) + set(CMAKE_SYSROOT $ENV{QNX_TARGET}) + + Cross Compiling for Windows CE ------------------------------ diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake index c5611b5..99447e4 100644 --- a/Modules/CMakeDetermineCompilerABI.cmake +++ b/Modules/CMakeDetermineCompilerABI.cmake @@ -161,6 +161,18 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) break() endif() endforeach() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL QCC) + foreach(dir ${implicit_dirs}) + if (dir MATCHES "/lib$") + get_filename_component(assumedArchDir "${dir}" DIRECTORY) + get_filename_component(archParentDir "${assumedArchDir}" DIRECTORY) + if (archParentDir STREQUAL CMAKE_SYSROOT) + get_filename_component(archDirName "${assumedArchDir}" NAME) + set(CMAKE_${lang}_LIBRARY_ARCHITECTURE "${archDirName}" PARENT_SCOPE) + break() + endif() + endif() + endforeach() endif() else() diff --git a/Modules/Compiler/QCC.cmake b/Modules/Compiler/QCC.cmake index 9df8269..10e1389 100644 --- a/Modules/Compiler/QCC.cmake +++ b/Modules/Compiler/QCC.cmake @@ -10,6 +10,9 @@ macro(__compiler_qcc lang) # http://www.qnx.com/developers/docs/6.4.0/neutrino/utilities/q/qcc.html#examples set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-V") + set(CMAKE_PREFIX_LIBRARY_ARCHITECTURE "ON") + + set(CMAKE_${lang}_COMPILE_OPTIONS_SYSROOT "-Wc,-isysroot,") set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-Wp,-isystem,") set(CMAKE_DEPFILE_FLAGS_${lang} "-Wp,-MD,<DEPFILE> -Wp,-MT,<OBJECT> -Wp,-MF,<DEPFILE>") diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx index d15ce57..766d347 100644 --- a/Source/cmSearchPath.cxx +++ b/Source/cmSearchPath.cxx @@ -181,7 +181,13 @@ void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths, const char* arch = this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"); if (arch && *arch) { - this->AddPathInternal(dir + subdir + "/" + arch, base); + if (this->FC->Makefile->IsDefinitionSet("CMAKE_SYSROOT") && + this->FC->Makefile->IsDefinitionSet( + "CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) { + this->AddPathInternal(cmStrCat('/', arch, dir, subdir), base); + } else { + this->AddPathInternal(cmStrCat(dir, subdir, '/', arch), base); + } } } std::string add = dir + subdir; -- cgit v0.12