I’m testing my CMake project (v3.16 to support at least Ubuntu 20.04 LTS and later). With QNX8, there are new warnings saying that “cc: warning - lang-c++ is deprecated”.
“In addition, projects that use -lang-c++ should use -x c++ instead.”
I don’t seem to be able to modify the behaviour of the variable CMAKE_CXX_COMPILE_OBJECT or CMAKE_CXX_LINK_EXECUTABLE in a toolchain file (it appears to be ignored).
Seeing the file Modules/Compiler/QCC-CXX.cmake and modifying it there does fix the warning.
I could do a string replace, but my concern here is that if it is deprecated in QNX 8.0, what if a newer version of QNX makes this an error?
Is there a best practice, or a recommended way to write a toolchain file to properly handle this, that would be considered portable from CMake 3.16 and later?
My toolchain file for now contains (works with QNX 7.1 and QNX 8)
Also, if I can’t upgrade CMake (QNX say they support Ubuntu 20.04/22.04/24.04, but obviously not in a CMake environment), what would be the best way to configure CMake to workaround without this patch?
I have to figure out how to test it myself actually since we lack CI for QCC at the moment. Unless you’re setting these variables manually in the toolchain file, you shouldn’t need to do anything once the diff is applied. I would try building CMake yourself and using it first. Once it is in a release, you can then download the prebuilt binaries and use them instead of the distro CMake.
Thanks. I was specifically asking if you can point to documentation so I can build cmake myself that confirms the change. Googling gives me how to build my own projects using cmake.
Can a test be implemented (even by my own project) that determines the compiler version before the code in the PR is run?
That looks fine to me. When I tested, all I did was source the .sh file from the QNX install, set the CC=qcc and CXX=q++ envvars, and pass -DCMAKE_SYSTEM_NAME=QNX down. CMake uses the toolchain file to find the compiler path to use (and set up targeting like you do) and then it will do its introspection to find out things like:
what is the compiler ID (paths are not reliable)
version
and from there it will end up going through the logic I patched to create the command line to use the compiler at build time.
I’m not having any luck testing. I don’t want to overwrite my existing install, so I checked out commit 8e1e1b9cf46177aa9ea0db2184e2d0c181d5794d
Built
$ mkdir build && cd build
$ ../bootstrap --parallel=32 && make -j32
$ DESTDIR=~/source/cmake/install make install
Check it worked with version
$ ~/source/cmake/install/usr/local/bin/cmake --version
cmake version 4.1.0-rc4-g8e1e1b9
Building my project fails very early with:
$ ~/source/cmake/install/usr/local/bin/cmake -B . -S ../.. -DCMAKE_TOOLCHAIN_FILE=../../../toolchain/qcc_aarch64le.cmake
...
-- Check for working CXX compiler: /home/jcurl/qnx/qnx800/host/linux/x86_64/usr/bin/q++
-- Check for working CXX compiler: /home/jcurl/qnx/qnx800/host/linux/x86_64/usr/bin/q++ - broken
CMake Error at /home/jcurl/source/cmake/install/usr/local/share/cmake-3.31/Modules/CMakeTestCXXCompiler.cmake:73 (message):
The C++ compiler
"/home/jcurl/qnx/qnx800/host/linux/x86_64/usr/bin/q++"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: '/home/jcurl/source/code.research/qnx/build/qnx8/CMakeFiles/CMakeScratch/TryCompile-ldAfuy'
Run Build Command(s): /home/jcurl/source/cmake/install/usr/local/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_75374/fast
/usr/bin/gmake -f CMakeFiles/cmTC_75374.dir/build.make CMakeFiles/cmTC_75374.dir/build
gmake[1]: Entering directory '/home/jcurl/source/code.research/qnx/build/qnx8/CMakeFiles/CMakeScratch/TryCompile-ldAfuy'
Building CXX object CMakeFiles/cmTC_75374.dir/testCXXCompiler.cxx.o
/home/jcurl/qnx/qnx800/host/linux/x86_64/usr/bin/q++ -Vgcc_ntoaarch64le -x c++ -Wp,-MD,CMakeFiles/cmTC_75374.dir/testCXXCompiler.cxx.o.d -Wp,-MT,CMakeFiles/cmTC_75374.dir/testCXXCompiler.cxx.o -Wp,-MF,CMakeFiles/cmTC_75374.dir/testCXXCompiler.cxx.o.d -o CMakeFiles/cmTC_75374.dir/testCXXCompiler.cxx.o -c /home/jcurl/source/code.research/qnx/build/qnx8/CMakeFiles/CMakeScratch/TryCompile-ldAfuy/testCXXCompiler.cxx
Linking CXX executable cmTC_75374
/home/jcurl/source/cmake/install/usr/local/bin/cmake -E cmake_link_script CMakeFiles/cmTC_75374.dir/link.txt --verbose=1
CMakeFiles/cmTC_75374.dir/testCXXCompiler.cxx.o:1:1: error: stray '\177' in program
1 | <U+007F>ELF<U+0002><U+0001><U+0001><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0001><U+0000><b7><U+0000><U+0001><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000>(<U+0002><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000><U+0000>@<U+0000><U+0000><U+0000><U+0000><U+0000>@<U+0000>
| ^~~~~~~~
I’m suspecting I haven’t set up paths properly.
Note, I did the same with
$ export PATH=~/source/cmake/install/usr/local/bin:$PATH
$ cmake --version
cmake version 4.1.0-rc4-g8e1e1b9
Any hints on how to build and have side-by-side without removing the version my distro provides?
Same results with commit 59d2fdf8fc425cdf71fad613ba7107f06d93c424
Ah, I forgot about that; I side-stepped it by setting CMAKE_TRY_COMPILE_TARGET_TYPE to STATIC_LIBRARY. Something is getting confused and the compiler is reading the object file and expecting source code. Perhaps the link command should continue using -lang-c++?
That fixed so it will build. There is a regression when building QNX 7.1.0, so it doesn’t work as expected, so older versions of QNX may now break.
For example, it now also uses -x c++ for QNX 7.1.0. While it works, I’m pretty sure that QNX 6.5.0 doesn’t support this option (I don’t have QNX 6.5.0 or a project to test with).
You’re relying on the version of the compiler, which on QNX 7.1 reports (CMake 3.22.1, CMake 4.1.0-rc4-g6845fa6):
CMAKE_CXX_COMPILER_VERSION = 8.3.0
On QNX 8.0, reports:
CMAKE_CXX_COMPILER_VERSION = 12.2.0
Please don’t do this for detecting the version of QNX. QNX can allow other compilers, not just GCC (qcc is a front-end wrapper, that might call GCC backend, or LLVM, or ICC, etc.).
My scripts used the variable CMAKE_SYSTEM_VERSION. This matches the description of the Operating system version we’re building for (e.g. 7.1.0 or 8.0.0).
Normally this variable isn’t set at all in my tests.
I’m not trying to detect the QNX version; this is specifically about q++ support and gcc should never see the code I’ve edited.
But if the compiler is not matching the system version, I’ll need to update the patch to check against 12.2.0. I’m not very familiar with QNX/qcc, so the toolchain not matching the advertised version in the installer was unexpected (though not surprising…macOS and Windows toolchain versioning is wonky too).
In both 7.x and 8.x, qcc can be used to build C code and q++ can be used to build C++ code (similar to gcc and g++). As far as I can tell there is no need for the lang flag on either version, and therefore no need to detect the version.
Am I missing something?
# To include compiler feature detection
include(Compiler/GNU-CXX)
include(Compiler/QCC)
__compiler_qcc(CXX)
# If the toolchain uses qcc for CMAKE_CXX_COMPILER instead of QCC, the
# default for the driver is not c++.
set(CMAKE_CXX_COMPILE_OBJECT
"<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
set(CMAKE_CXX_LINK_EXECUTABLE
"<CMAKE_CXX_COMPILER> <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")