microsoft / vscode-cpptools

Official repository for the Microsoft C/C++ extension for VS Code.
Other
5.5k stars 1.55k forks source link

Problem with system include paths from QNX7 `qcc` compiler #10403

Closed mccolljr closed 1 year ago

mccolljr commented 1 year ago

I'm having trouble getting the QNX7 qcc cross-compiler to play nice with intellisense. It seems like the issue is that the cpptools extension is failing to get the proper system include paths from the qcc compiler, and so is falling back to include paths from the host machine.

The problem, as it appears in the editor:

image

The project I'm working in is a large and complicated CMake project.

This is my c_cpp_properties.json:

{
    "configurations": [
        {
            "name": "CMake",
            "configurationProvider": "ms-vscode.cpptools",
            "compileCommands": ".vscode/compile_commands.json",
        }
    ],
    "version": 4
}

Debug logs from cpptools:

loggingLevel: Debug
cpptools/didChangeCppProperties
Code browsing service initialized
Attempting to get defaults from compiler found on the machine: '/usr/bin/gcc'
Compiler query command line: /usr/bin/gcc -std=gnu++14 -m64 -Wp,-v -E -dM -x c++ /dev/null
Attempting to get defaults from compiler found on the machine: '/usr/bin/gcc'
Compiler query command line: /usr/bin/gcc -std=gnu17 -m64 -Wp,-v -E -dM -x c /dev/null
Attempting to get defaults from C++ compiler in compile_commands.json file: '/home/adb/qnx700/host/linux/x86_64/usr/bin/qcc'
Querying compiler for default C++ language standard using command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -x c++ -E -dM /dev/null
Querying compiler for default C++ language standard using command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -x c++ -E -dM /dev/null
Querying compiler for default C language standard using command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -x c -E -dM /dev/null
Querying compiler for default C language standard using command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -x c -E -dM /dev/null
Querying compiler's default target using command line: "/home/adb/qnx700/host/linux/x86_64/usr/bin/qcc" -dumpmachine
Unhandled default compiler target value detected: 
Compiler query command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -Vgcc_ntox86_64_gpp -lang-c++ -Wc,-std=c++14 -g -g -std=c++17 -m64 -Wp,-v -E -dM -x c++ /dev/null
Failed to query compiler. Falling back to 32-bit intelliSenseMode.
Compiler query command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -Vgcc_ntox86_64_gpp -lang-c++ -Wc,-std=c++14 -g -g -std=c++17 -m32 -Wp,-v -E -dM -x c++ /dev/null
Failed to query compiler. Falling back to no bitness.
Compiler query command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -Vgcc_ntox86_64_gpp -lang-c++ -Wc,-std=c++14 -g -g -std=c++17 -Wp,-v -E -dM -x c++ /dev/null
cc: unknown option: '-dM'

Attempting to get defaults from C++ compiler in compile_commands.json file: '/home/adb/qnx700/host/linux/x86_64/usr/bin/qcc'
Attempting to get defaults from C++ compiler in compile_commands.json file: '/home/adb/qnx700/host/linux/x86_64/usr/bin/qcc'
Attempting to get defaults from C++ compiler in compile_commands.json file: '/home/adb/qnx700/host/linux/x86_64/usr/bin/qcc'
Attempting to get defaults from C++ compiler in compile_commands.json file: '/home/adb/qnx700/host/linux/x86_64/usr/bin/qcc'
Attempting to get defaults from C++ compiler in compile_commands.json file: '/home/adb/qnx700/host/linux/x86_64/usr/bin/qcc'
Compiler query command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -Vgcc_ntox86_64_gpp -lang-c++ -Wc,-std=c++14 -g -g -std=c++17 -m64 -Wp,-v -E -dM -x c++ /dev/null
Failed to query compiler. Falling back to 32-bit intelliSenseMode.
Compiler query command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -Vgcc_ntox86_64_gpp -lang-c++ -Wc,-std=c++14 -g -g -std=c++17 -m32 -Wp,-v -E -dM -x c++ /dev/null
Failed to query compiler. Falling back to no bitness.
Compiler query command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -Vgcc_ntox86_64_gpp -lang-c++ -Wc,-std=c++14 -g -g -std=c++17 -Wp,-v -E -dM -x c++ /dev/null
cc: unknown option: '-dM'

Attempting to get defaults from C++ compiler in compile_commands.json file: '/home/adb/qnx700/host/linux/x86_64/usr/bin/qcc'
Attempting to get defaults from C++ compiler in compile_commands.json file: '/home/adb/qnx700/host/linux/x86_64/usr/bin/qcc'
Compiler query command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -Vgcc_ntox86_64_gpp -lang-c++ -Wc,-std=c++14 -g -g -std=c++17 -m64 -Wp,-v -E -dM -x c++ /dev/null
Failed to query compiler. Falling back to 32-bit intelliSenseMode.
Compiler query command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -Vgcc_ntox86_64_gpp -lang-c++ -Wc,-std=c++14 -g -g -std=c++17 -m32 -Wp,-v -E -dM -x c++ /dev/null
Failed to query compiler. Falling back to no bitness.
Compiler query command line: /home/adb/qnx700/host/linux/x86_64/usr/bin/qcc -Vgcc_ntox86_64_gpp -lang-c++ -Wc,-std=c++14 -g -g -std=c++17 -Wp,-v -E -dM -x c++ /dev/null
cc: unknown option: '-dM'

[... etc, a lot more like this]

It seems like the problem is that passing -dM to the qcc compiler results in the compiler complaining about the unrecognized argument.

If I run the compiler query command with the -dM argument removed, I get what looks like the expected output:

ignoring duplicate directory "/home/adb/qnx700/host/linux/x86_64/usr/lib/gcc/x86_64-pc-nto-qnx7.0.0/5.4.0/include"
ignoring nonexistent directory "/home/adb/qnx700/target/qnx7/usr/x86_64-pc-nto-qnx7.0.0/include"
ignoring duplicate directory "/home/adb/qnx700/target/qnx7/usr/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/adb/qnx700/host/linux/x86_64/usr/lib/gcc/x86_64-pc-nto-qnx7.0.0/5.4.0/include
 /home/adb/qnx700/target/qnx7/usr/include/c++/5.4.0
 /home/adb/qnx700/target/qnx7/usr/include/c++/5.4.0/x86_64-pc-nto-qnx7.0.0
 /home/adb/qnx700/target/qnx7/usr/include/c++/5.4.0/backward
 /home/adb/qnx700/target/qnx7/usr/include
End of search list.
# 1 "/dev/null"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/dev/null"

How is this compiler query command built? Is there any way that I can affect the arguments it attempts to pass to qcc?

Colengms commented 1 year ago

Hi @mccolljr . The C/C++ Extension attempts to query gcc, clang, and compilers based on those which support the same command line arguments. It sounds like qcc may not support the standard gcc compiler options we rely on. Perhaps it's not based on gcc directly?

cc: unknown option: '-dM'

The -dM option, specifically, is used to solicit the list of defines supported by the compiler.

https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#Preprocessor-Options

-dM
Instead of the normal output, generate a list of ‘#define’ directives for all the macros defined during the execution of the preprocessor, including predefined macros. This gives you a way of finding out what is predefined in your version of the preprocessor.

https://www.qnx.com/developers/docs/6.5.0SP1.update/com.qnx.doc.neutrino_utilities/q/qcc.html

That said, we could keep this issue open to track finding a way to fully support qcc. Perhaps they've provided other ways to extract the information we need. You might also consider opening an issue against the compiler to request they add support for outputting defines and system includes. If qcc is based on the code to gcc, you might suggest they restore some of the missing gcc arguments, to improve compatibility with tools that interop with gcc-based compilers.

In the meanwhile, you could disable compiler querying by setting "compilerPath": "" in your configuration. This will override the compiler used in your compile_commands.json. If needed for full IntelliSense support, you could add the system includes and needed system defines directly in your configuration using includePath and defines fields.

mccolljr commented 1 year ago

Hey @Colengms

Thanks for getting back to me so quickly. I'm away from my machine right now - I can follow up on some of your questions tomorrow.

In the meantime - one of my struggles is that this project builds for 4 different target systems. Each one uses a separate compiler. We have 2 QNX targets (QNX7 and QNX6.5), one embedded Linux system, and one desktop system. The two that exhibit this issue are the QNX targets. Unfortunately we are locked into the version of the compiler(s) associated with our QNX licenses. It would be nice to get upstream support for gcc-aligned flags, but I don't think there's much we can do in that direction. We're a relatively small customer and we aren't licensed on the most up-to-date version of the compiler at the moment.

Additionally, we have everything defined in cmake toolchain files - including some additional compile definitions that are project-specific. It would be nice if we could find a way to keep cmake the source of truth for all of this.

In any case - thanks for your suggestions. I will play with some of them tomorrow and see if I can get something working with our environment.

mccolljr commented 1 year ago

I've been playing with this this morning, and I've learned a couple of things:

While qcc (+ the accompanying q++) is not gcc-compatible, it is more or less a wrapper around several different platform-specific builds of gcc, also available within the tooling provided by the QNX software suite. I was able to get both our build + intellisense working by directly referencing the appropriate versions of the included gcc compiler in our cmake toolchain files.

At some point it would be nice to be able to support using qcc in our cmake directly, with a pathway to point the cpptools extension at the gcc version for the target platform for compiler queries, but at the moment I think this is resolved.