1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_ide-design-cpp: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker======================= 4*61c4878aSAndroid Build Coastguard WorkerC/C++ code intelligence 5*61c4878aSAndroid Build Coastguard Worker======================= 6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module-subpage:: 7*61c4878aSAndroid Build Coastguard Worker :name: pw_ide 8*61c4878aSAndroid Build Coastguard Worker 9*61c4878aSAndroid Build Coastguard WorkerPigweed projects have a few characteristics that make it challenging for some 10*61c4878aSAndroid Build Coastguard WorkerIDEs and language servers to support C/C++ code intelligence out of the box: 11*61c4878aSAndroid Build Coastguard Worker 12*61c4878aSAndroid Build Coastguard Worker* Pigweed projects generally don't use the default host toolchain. 13*61c4878aSAndroid Build Coastguard Worker 14*61c4878aSAndroid Build Coastguard Worker* Pigweed projects usually use multiple toolchains for separate targets. 15*61c4878aSAndroid Build Coastguard Worker 16*61c4878aSAndroid Build Coastguard Worker* Pigweed projects rely on the build system to define the relationship between 17*61c4878aSAndroid Build Coastguard Worker :ref:`facades and backends<docs-module-structure-facades>` for each target. 18*61c4878aSAndroid Build Coastguard Worker 19*61c4878aSAndroid Build Coastguard WorkerThese challenges are common to embedded projects in general. 20*61c4878aSAndroid Build Coastguard Worker 21*61c4878aSAndroid Build Coastguard WorkerWe've found that the best solution is to use the 22*61c4878aSAndroid Build Coastguard Worker`clangd <https://clangd.llvm.org/>`_ language server or alternative language 23*61c4878aSAndroid Build Coastguard Workerservers that use the same 24*61c4878aSAndroid Build Coastguard Worker`compilation database format <https://clang.llvm.org/docs/JSONCompilationDatabase.html>`_ 25*61c4878aSAndroid Build Coastguard Workerand comply with the language server protocol. Usually, your build system 26*61c4878aSAndroid Build Coastguard Workergenerates the compilation database, and we supplement that with Pigweed 27*61c4878aSAndroid Build Coastguard Workertools to produce target-specific compilation databases that work well with 28*61c4878aSAndroid Build Coastguard Workerlanguage servers. 29*61c4878aSAndroid Build Coastguard Worker 30*61c4878aSAndroid Build Coastguard Worker------------------------------------------- 31*61c4878aSAndroid Build Coastguard WorkerSupporting ``clangd`` for embedded projects 32*61c4878aSAndroid Build Coastguard Worker------------------------------------------- 33*61c4878aSAndroid Build Coastguard WorkerThere are three main challenges that often prevent ``clangd`` from working 34*61c4878aSAndroid Build Coastguard Workerout-of-the-box with embedded projects: 35*61c4878aSAndroid Build Coastguard Worker 36*61c4878aSAndroid Build Coastguard Worker#. Embedded projects cross-compile using alternative toolchains, rather than 37*61c4878aSAndroid Build Coastguard Worker using the system toolchain. ``clangd`` doesn't know about those toolchains 38*61c4878aSAndroid Build Coastguard Worker by default. 39*61c4878aSAndroid Build Coastguard Worker 40*61c4878aSAndroid Build Coastguard Worker#. Embedded projects (particularly Pigweed projects) often have *multiple* 41*61c4878aSAndroid Build Coastguard Worker targets that use *multiple* toolchains. Most build systems that generate 42*61c4878aSAndroid Build Coastguard Worker compilation databases put all compile commands in a single database, meaning 43*61c4878aSAndroid Build Coastguard Worker a single file can have multiple, conflicting compile commands. ``clangd`` 44*61c4878aSAndroid Build Coastguard Worker will typically use the first one it finds, which may not be the one you want. 45*61c4878aSAndroid Build Coastguard Worker 46*61c4878aSAndroid Build Coastguard Worker#. Pigweed projects have build steps that use languages other than C/C++. These 47*61c4878aSAndroid Build Coastguard Worker steps are not relevant to ``clangd`` but some build systems will include them 48*61c4878aSAndroid Build Coastguard Worker in the compilation database anyway. 49*61c4878aSAndroid Build Coastguard Worker 50*61c4878aSAndroid Build Coastguard WorkerTo deal with these challenges, ``pw_ide`` processes the compilation database(s) 51*61c4878aSAndroid Build Coastguard Workeryou provide, yielding one or more compilation databases that are valid, 52*61c4878aSAndroid Build Coastguard Workerconsistent, and specific to a particular target and toolchain combination. 53*61c4878aSAndroid Build Coastguard WorkerThis enables code intelligence and navigation features that accurately reflect 54*61c4878aSAndroid Build Coastguard Workera specific build. 55*61c4878aSAndroid Build Coastguard Worker 56*61c4878aSAndroid Build Coastguard WorkerAfter processing a compilation database, ``pw_ide`` knows what targets are 57*61c4878aSAndroid Build Coastguard Workeravailable and provides tools for selecting which target the language server 58*61c4878aSAndroid Build Coastguard Workershould use. Then ``clangd``'s configuration is changed to use the compilation 59*61c4878aSAndroid Build Coastguard Workerdatabase associated with that target. 60*61c4878aSAndroid Build Coastguard Worker 61*61c4878aSAndroid Build Coastguard Worker---------------------- 62*61c4878aSAndroid Build Coastguard WorkerImplementation details 63*61c4878aSAndroid Build Coastguard Worker---------------------- 64*61c4878aSAndroid Build Coastguard Worker.. tab-set:: 65*61c4878aSAndroid Build Coastguard Worker 66*61c4878aSAndroid Build Coastguard Worker .. tab-item:: Bazel 67*61c4878aSAndroid Build Coastguard Worker 68*61c4878aSAndroid Build Coastguard Worker Bazel doesn't have native support for generating compile commands, so it's 69*61c4878aSAndroid Build Coastguard Worker common to rely on outside tools. In the 70*61c4878aSAndroid Build Coastguard Worker :ref:`Pigweed Visual Studio Code extension<module-pw_ide-guide-vscode>`, 71*61c4878aSAndroid Build Coastguard Worker we use the `Bazel Compile Commands Extractor <https://github.com/hedronvision/bazel-compile-commands-extractor>`_. 72*61c4878aSAndroid Build Coastguard Worker 73*61c4878aSAndroid Build Coastguard Worker .. tab-item:: GN 74*61c4878aSAndroid Build Coastguard Worker 75*61c4878aSAndroid Build Coastguard Worker Invoking GN with the ``--export-compile-commands`` flag (e.g. 76*61c4878aSAndroid Build Coastguard Worker ``gn gen out --export-compile-commands``) will output a compilation 77*61c4878aSAndroid Build Coastguard Worker database in the ``out`` directory along with all of the other GN build 78*61c4878aSAndroid Build Coastguard Worker outputs (in other words, it produces the same output as ``gn gen out`` 79*61c4878aSAndroid Build Coastguard Worker but *additionally* produces the compilation database). You can remove the 80*61c4878aSAndroid Build Coastguard Worker need to explicitly provide the flag by adding this to your ``.gn`` file: 81*61c4878aSAndroid Build Coastguard Worker ``export_compile_commands = [ ":*" ]``. 82*61c4878aSAndroid Build Coastguard Worker 83*61c4878aSAndroid Build Coastguard Worker The database that GN produces will have all compile commands for all 84*61c4878aSAndroid Build Coastguard Worker targets, which is a problem for the reasons described above. It will also 85*61c4878aSAndroid Build Coastguard Worker include invocations of certain Pigweed Python scripts that are not valid 86*61c4878aSAndroid Build Coastguard Worker C/C++ compile commands and cause ``clangd`` to fault. So these files need 87*61c4878aSAndroid Build Coastguard Worker to be processed to: 88*61c4878aSAndroid Build Coastguard Worker 89*61c4878aSAndroid Build Coastguard Worker * Filter out invalid compile commands 90*61c4878aSAndroid Build Coastguard Worker 91*61c4878aSAndroid Build Coastguard Worker * Separate compile commands into separate databases for each target 92*61c4878aSAndroid Build Coastguard Worker 93*61c4878aSAndroid Build Coastguard Worker * Resolve relative paths so ``clangd`` can find tools in the Pigweed 94*61c4878aSAndroid Build Coastguard Worker environment 95*61c4878aSAndroid Build Coastguard Worker 96*61c4878aSAndroid Build Coastguard Worker The :ref:`pw_ide CLI<module-pw_ide-guide-cli>` does all of this when you 97*61c4878aSAndroid Build Coastguard Worker run the ``sync`` command. 98*61c4878aSAndroid Build Coastguard Worker 99*61c4878aSAndroid Build Coastguard Worker .. tab-item:: CMake 100*61c4878aSAndroid Build Coastguard Worker 101*61c4878aSAndroid Build Coastguard Worker Enabling the ``CMAKE_EXPORT_COMPILE_COMMANDS`` option ensures that 102*61c4878aSAndroid Build Coastguard Worker compilation databases are produced along with the rest of the CMake build. 103*61c4878aSAndroid Build Coastguard Worker This can be done either in your project's ``CMakeLists.txt`` (i.e. 104*61c4878aSAndroid Build Coastguard Worker ``set(CMAKE_EXPORT_COMPILE_COMMANDS ON)``), or by setting the flag when 105*61c4878aSAndroid Build Coastguard Worker invoking CMake (i.e. ``-DCMAKE_EXPORT_COMPILE_COMMANDS=ON``). 106*61c4878aSAndroid Build Coastguard Worker 107*61c4878aSAndroid Build Coastguard Worker CMake will generate separate ``compile_commands.json`` files that are 108*61c4878aSAndroid Build Coastguard Worker specific to each target in the target's build output directory. These 109*61c4878aSAndroid Build Coastguard Worker files are *already* in the format we need them to be in, so the only 110*61c4878aSAndroid Build Coastguard Worker thing Pigweed needs to provide is a mechanism for discovering those 111*61c4878aSAndroid Build Coastguard Worker targets and pointing ``clangd`` at the appropriate file. 112*61c4878aSAndroid Build Coastguard Worker 113*61c4878aSAndroid Build Coastguard Worker.. _module-pw_ide-design-cpp-target-groups: 114*61c4878aSAndroid Build Coastguard Worker 115*61c4878aSAndroid Build Coastguard Worker------------- 116*61c4878aSAndroid Build Coastguard WorkerTarget groups 117*61c4878aSAndroid Build Coastguard Worker------------- 118*61c4878aSAndroid Build Coastguard WorkerRunning code intelligence on the compilation database of a single target is the 119*61c4878aSAndroid Build Coastguard Workermost *consistent* approach, but it's not always the most *useful*. For example, 120*61c4878aSAndroid Build Coastguard Workerapplication code and test code are usually built in separate targets, but it's 121*61c4878aSAndroid Build Coastguard Workera nuisance to switch code intelligence targets as you move back and forth 122*61c4878aSAndroid Build Coastguard Workerbetween application code and test code. 123*61c4878aSAndroid Build Coastguard Worker 124*61c4878aSAndroid Build Coastguard WorkerWe address this through the use of "target groups", which in which a compilation 125*61c4878aSAndroid Build Coastguard Workerdatabase is build by intentionally combining the compile commands from several 126*61c4878aSAndroid Build Coastguard Workerrelated targets. Continuing the previous example, you might have a target 127*61c4878aSAndroid Build Coastguard Workergroup that contains both the application code and test code to eliminate the 128*61c4878aSAndroid Build Coastguard Workernuisance of repeatedly switching between those targets. The compile commands 129*61c4878aSAndroid Build Coastguard Workerfor the application code would be higher in the list than those for test code, 130*61c4878aSAndroid Build Coastguard Workerso in a conflict (e.g., a test that uses a different backend from the 131*61c4878aSAndroid Build Coastguard Workerapplication code), you will get code intelligence for the application code. This 132*61c4878aSAndroid Build Coastguard Workeris usually an acceptable trade-off. 133