Yaskawa-Global / motoros2

ROS 2 (rcl, rclc & micro-ROS) node for MotoPlus-compatible Yaskawa Motoman robot controllers
101 stars 21 forks source link

VS intelli-sense has difficulty parsing headers #44

Open ted-miller opened 1 year ago

ted-miller commented 1 year ago

There's a LOT of red squiggles indicating code errors. However, this builds just fine.

I suspect that either the order of folders in the intellisense-search-path is incorrect, or it's caused by the monolithic MotoROS2.h that includes everything in one place.

gavanderhoorn commented 1 year ago

I'm not sure whether this just affects IntelliSense.

To appease a static analysis tool I'm trialling, I sorted all #includes alphabetically in MotoROS.h. That by itself caused the build to fail. Reverting the change made things work again.

We might want to switch to an IWYU style, which should help avoid this.

Might also help IntelliSense make sense (hah) of everything again (but I'm not sure about that).

gavanderhoorn commented 1 year ago

Looking into this a bit: I believe this (ie: intellisense complaining about certain headers) is caused by the fact it's by default incapable of processing non-MSVC targeting headers.

In contrast to VS Code, VS is difficult to configure for cross-compilation / non-MSVC toolchains. That is, with msbuild / native projects.

Where in VS Code it's almost trivial to teach the C++ plugin how to talk to a non-MSVC toolchain, VS doesn't really seem to support it, unless you use the Open Directory and/or CMake project features.

Here is some output from the Intellisense debug log when it's parsing headers for CommunicationExecutor.c:

Click to expand ``` <8476> [IntelliSense] UpdateRange: (84) with pos range (0, 1000) - C:\Users\user\dev\motoros2\src\CommunicationExecutor.c <8476> [IntelliSense] Translation Unit: C:\Users\user\dev\motoros2\src\CommunicationExecutor.c <8476> [IntelliSense] Project Name: C:\USERS\USER\DEV\MOTOROS2\SRC\MOTOROS2_ALLCONTROLLERS.VCXPROJ <8476> [IntelliSense] Project GUID: {64C31524-A3C4-49D4-AD04-955D44202226} <8476> [IntelliSense] Priority: Normal <8476> [IntelliSense] Configuration Name: YRC1000_humble|Win32 <8476> [IntelliSense] Toolset IntelliSense Identifier: < EMPTY > <8476> [IntelliSense] command line options: /c /W1 /WX- /DMOTOROS2_MEM_TRACE_ENABLE /DCPU=_VX_ATOM /DTOOL_FAMILY=gnu /DTOOL=gnu /DYRC1000 /D_WRS_KERNEL /DYASKAWA_MOTOMAN_MOTOPLUS1_GCC43 /DYASKAWA_MOTOMAN_MOTOPLUS1 /EHsc /MD /fp:precise /Zc:wchar_t /Zc:forScope /Gd /errorReport:prompt /TP /IC:\Users\user\dev\motoros2\libmicroros_yrc1000_humble\include /IC:\Program Files\MotoPlus for Visual Studio\YRC1000\inc /IC:\Program Files\MotoPlus for Visual Studio\YRC1000\gnu\4.3.3-vxworks-6.9\lib\gcc\i586-wrs-vxworks\4.3.3\include /IC:\Program Files\MotoPlus for Visual Studio\YRC1000\gnu\4.3.3-vxworks-6.9\lib\gcc\i586-wrs-vxworks\4.3.3\include-fixed /IC:\Users\user\dev\motoros2\src\..\libmicroros_yrc1000_humble\include /IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\include /IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\atlmfc\include /IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include /IC:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\ucrt /IC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\UnitTest\include /AIC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\atlmfc\lib\x86 /AIC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\lib\x86 /AIC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\lib\x86 /AIC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\atlmfc\lib\x86 /AIC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\lib\x86 /AIC:\Program Files (x86)\Windows Kits\10\lib\10.0.15063.0\ucrt\x86 /AIC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\UnitTest\lib /BCDC:\Users\user\dev\motoros2\src\\ C:\USERS\user\dev\MOTOROS2\SRC\COMMUNICATIONEXECUTOR.C /AutoPCHC:\Users\user\dev\motoros2\.vs\MotoROS2\v17\ipch\AutoPCH\ff2685c0ef9ae1d1 ```

I've added some missing defines, but notice how it's still adding all sorts of MSVC specific include dirs for Windows application frameworks and VS libs.

It seems like it's treating this as just-another-vs-windows-project, which obviously won't work, as mpBuilder and M+ are all GCC based.


There might be ways around this (defining a custom cross-compilation toolset in an extension, or using a special intellisense header), but I'm not sure whether those would be worth the effort.

I'm also not a VS expert, so I'm not sure what I write is even correct.


Edit: link dump:

gavanderhoorn commented 1 year ago

Looked into this some more.

From what I can gather, the issues are with IntelliSense. In the default M+ SDK configuration, VS will essentially assume the project is MS VC++ based, and will configure the intellisense compiler/parser to parse C++ with MSVC-isms in them (VS also passes a large number of Windows/VC.CRT/WinRT and other unneeded include directories to IntelliSense, but that can be avoided by removing almost everything from the VC++ Directories project property page).

This fails in many places in libmicroros, as instead of the __GNUC__, __LINUX__ and/or YASKAWA_MOTOMAN_MOTOPLUS1 code paths, the _WIN32 ones are processed (I haven't been able to find where _WIN32 gets defined, but it definitely is: #undef-ing it reduces the number of parsing errors reported significantly).

Additionally, IntelliSense does not 'know' about any of the (built-in) defines the M+ GCC cross-compiler comes with, leading to more parsing problems (already in the M+ SDK headers themselves, as they check for things like __VXWORKS__ and a bunch of other stuff which MSVC doesn't set). This leads to a cascade of problems, as all other code (ie: MotoROS2, but also the various packages in our libmicroros) depend on a sane set of types and constants and they're not getting them -- and IntelliSense certainly isn't able to make any sense out of it.

Summarising, I believe there are two main issues:

  1. IntelliSense expects to parse MS VC++ code, targetting a Windows platform/run env
  2. IntelliSense is not aware of the specifics of the M+ SDK GCC cross-compiler (ie: it does not have information about built-in types, defines, constants)

Having written all of that: the IntelliSense parser/compiler shipped with VS22 is capable of parsing headers targetting GCC and Clang. It uses a special mode for this, enabled using the /ClangMode command line argument.

VS22 does pass that argument when it needs to, but I've only seen this happen with "Open Folder" and CMake projects, where the intelliSenseMode setting (in CppProperties.json) was set to one of the linux-*-* values such as linux-gcc-x86.

That setting makes everything work almost immediately, but does not seem to exist for native VS projects / solutions (or: I've not been able to find it).


Some things I've tried and which get the number of parsing errors down to about 1500 (from over 30000 initially):

gavanderhoorn commented 1 year ago

Not a solution at all, but: https://github.com/Yaskawa-Global/motoros2/compare/main...gavanderhoorn:motoros2:vs_intellisense_tweaking.