Creating Advanced CMake Projects for Raspberry Pi

This tutorial shows how to use the new VisualGDB CMake Project Subsystem to create and manage advanced CMake-based projects for Rasberry Pi. We will start with creating a new project, show how to edit various settings and create a few additional targets.

Before you begin, install VisualGDB 5.3 or later.

  1. Start Visual Studio and open VisualGDB Linux Project Wizard:01-prj
  2. Select Create a new project -> Application -> Use CMake. Ensure the “Use the advanced CMake Project Subsystem” checkbox is checked:02-subsys
  3. On the next page select “Build the project locally with a cross-compiler” and click “Finish” to create the project:03-target
  4. VisualGDB will download and install a special build of CMake that reports advanced properties of the targets and lets VisualGDB automatically edit them in response to changing various settings via Visual Studio GUI:04-getcmake
  5. Once the project is created, its contents will appear in Solution Explorer. Unlike regular C++ projects where each project corresponds to one target, VisualGDB CMake projects can recognize and show multiple targets if they are defined in your CMakeLists.txt files. The basic project created by VisualGDB wizard has only one target:05-built
  6. Build the project and ensure you can debug it:06-debug
  7. Now we will show how to edit various project properties. Right-click on the “Source Files” folder and select “Add->New Item”:07-newfile
  8. Select “C++ Source File” and click “Add”:08-cppfile
  9. Note how VisualGDB automatically updates the add_executable() statement:09-lists
  10. Now right-click on the project itself and select “Add->New Item” again:10-addnew
  11. Select “Shared Library” and change the “Location” to <project directory>/subfolder:sh
  12. VisualGDB will automatically create the subfolder and put another CMakeLists.txt file in it. Replace the contents of the SharedLibrary.cpp file with this:
    #include <stdio.h>
     
    void SharedLibraryFunction()
    {
        printf("Hello from shared library\n");
    }

    Then add a SharedLibrary.h file with the following contents:

    #pragma once
     
    void SharedLibraryFunction();
  13. Right-click on the library in Solution Explorer and click “Go To Definition”:12-goto
  14. VisualGDB will open the CMakeLists.txt file containing the definition of SharedLibrary:def
  15. Try including the SharedLibrary.h from the main executable and build the project. The build will fail because the “subfolder” is not added to the header search path of the main executable: 13-builderror
  16. Instead of adding it directly to the main executable, we will instead configure the SharedLibrary to “export” this directory to every target that references it. Open Visual Studio properties for Shared Library and add “.” to Exported Settings -> Interface -> Additional Include Directories: 14-iface
  17. Then add a reference from the main executable to the library:15-addref
  18. The Reference Manager window will show all libraries directly referenced by the edited target letting you conveniently edit them via the GUI:16-ref
  19. Build the project now. Both the library and the executable should be built successfully:17-build
  20. Modify the main() functionto call SharedLibraryFunction() and ensure you can step into it:18-stepin
  21. Add another executable to the project:19-exe2
  22. Right-click on it in Solution Explorer and select “Debug->Start New Instance”. See how VisualGDB launches the selected executable. Open the GDB Session window and take a note of the set solib-search-path command automatically issued by VisualGDB:20-pathThis command tells the gdb debugger where to search for the libraries if they were not built on the same machine where they are debugged.
  23. Start debugging the first target again: 21-debug
  24. As the first executable references the shared library, VisualGDB has automatically deployed it and added its location to the “solib-search-path” variable, so you don’t need to do it yourself:22-solib2
  25. Now we will show how to edit various target settings. Select both executables, open Visual Studio properties and set Preprocessor Definitions to MY_CUSTOM_MACRO:23-setmacro
  26. See how VisualGDB edited the CMakeLists.txt file in response:24-macro
  27. Unlike the regular Visual C++ projects that need to be synchronized with the CMake files, VisualGDB CMake projects always reflect the latest state of the CMake files. Try editing the target_compile_definitions() statement as shown below: 25-custom
  28. Then open Visual Studio properties for the target and add 3 more macros:26-edit
  29. See how VisualGDB automatically detected the format (indentation and the 2 variables per line limit) and edited the statement accordingly:27-format

Unlike the regular Visual C++ projects that duplicate information from the CMakeLists.txt files, the VisualGDB CMake projects always store all the information in the CMake files. Each time you open a CMake project, VisualGDB invokes CMake to report the structure of the project and displays it in Solution Explorer. When you add/remove targets or source files, or when you edit target properties, VisualGDB locates the relevant statements inside CMake files and edits them, leaving the rest of the files intact. This mechanism is very robust and supports both projects generated via VisualGDB wizard and imported 3rd-party projects.

Note that if your CMake projects define targets or change target settings using macros, VisualGDB will use the correct settings in Solution Explorer and IntelliSense Settings, but will ignore the statements that affect multiple targets when editing target properties via Visual Studio property window.