Building & Debugging Blender with Visual Studio Code

Visual Studio Code is an open source and multiplatform IDE for code editing (and compiling, debugging, etc.) available here : https://code.visualstudio.com/

I wanted to see if I could build, run and debug Blender using this IDE, and the anwser is : yes. Here is how to do it.

Edit: Updated the scripts and configuration of Visual Studio Code (no longer requires an CMake install, will load scripts and datafiles directly from the sources)

Setup

Based on : https://wiki.blender.org/index.php/Dev:Doc/Building_Blender/Linux/Generic_Distro/CMake.

I’m using the following folder hierarchy to build:

Blender         # with a B.
   |--- blender # with a b, this is a clone of the Blender source repository
   |--- libs    # will contains Blender's dependencies (external libraries)

So, first step is to create this structure, retrieve the Blender sources, and build the dependencies. To do that, here is the bootstrap script I’m using (put that in a bootstrap.sh file and execute it)

# create our root folder
mkdir Blender
cd Blender

# this will download Blender's sources
git clone --recursive https://git.blender.org/blender.git

# now create the libs folders
mkdir -p libs/sources
mkdir -p libs/install

# and build them. Note that the source and install path need
# to be absolute
./blender/build_files/build_environment/install_deps.sh \
    --with-all                                          \
    --source $PWD/libs/sources                          \
    --install $PWD/libs/install

This can take quite a bit of time, depending on your computer. But you only need to do it once (well, sometime the libs are updated, but it doesn’t happen very often)

Also, after this is done, you’ll notice a file BUILD_NOTES.txt in the root Blender folder. This is a generated file which contains useful information about the dependencies (we’ll use this file to configure Visual Studio Code to build Blender)

Install Visual Studio Code

Once you’ve installed Visual Studio Code, install the following addons :

  • C/C++ (Microsoft) – C/C++ support. Required
  • CMake (twxs) – CMake syntax coloring, code completion, etc. Optional but useful if you have to modify a CMake script file
  • CMake Tools (Microsoft) – Add Configure/Build features based on CMake. Required
  • Clang-Format (xaver) – Used to automatically format code to follow Blender’s coding style. Optional but highly recommended if you want to contribute.

Note that CMake Tools plugin requires CMake version 3.7.1 or greater, with server mode enabled (if you installed a recent prebuilt version from the CMake website, it should be enabled by default. But if you build your own, make sure it’s enabled)

Build

Now, open Visual Studio Code, and open the Blender/blender folder. If CMake Tools worked correctly, the status bar should look like this:

Before going further, we will setup the project to configure CMake to use the dependencies. In the sources (Blender/blender) create a .vscode folder. In this folder, create a settings.json file:

{
    // Where Blender is built. DO NOT BUILD IN SOURCES !
    "cmake.buildDirectory": "${workspaceRoot}/../build",

    // If you want to generate an install of Blender, setup this path:
    "cmake.installPrefix":  "${workspaceRoot}/../install"

    // The options used by CMake to configure how Blender is built
    "cmake.configureSettings": {
        // this part comes from the BUILD_NOTES.txt file generated when we build the libs
        "WITH_CODEC_SNDFILE": "ON",
        "PYTHON_VERSION": "3.7",
        "WITH_OPENCOLORIO": "ON",
        // ... the rest of the file
    },

    // Clang-format options (only if your installed the extension)
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "xaver.clang-format"
}

Notice that the options in BUILD_NOTES.txt are not formatted the same way as CMake Tools want, so you need to format them like in the example above.

Now after this step, you’ll be able to build Blender. Just setup the kit you want to use, select the build type (both actions are done using the CMake Tools helpers that appear on the status bar, on the bottom-left of Visual Studio Code) and hit F7

Debug

Time for fun! Blender is built, we’d like to dive in the code. There’s one last thing to do: add a launch configuration. Indeed, unless you make an install, the scripts and datafiles are not accessible to the Blender’s executable. So to debug, we need to create a launch.json next to our settings.json file.

This is the content on my file on Linux, with comments on the relevent sections:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            // path to the Blender's executable
            "program": "${command:cmake.buildDirectory}/bin/blender",
            // in here you can add arguments that will be passed to blender when the debugging session starts
            "args": [],
            "stopAtEntry": false,
            // by default it runs in the source folder, but you can use any other you like
            "cwd": "${workspaceFolder}",
            // this one is the most important! Without those environment variable, Blender will fail to start because it won't find its Python scripts and data files.
            "environment": [
                { "name": "BLENDER_SYSTEM_SCRIPTS", "value": "${workspaceFolder}/release/scripts" },
                { "name": "BLENDER_SYSTEM_DATAFILES", "value": "${workspaceFolder}/release/datafiles" }
            ],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [ { "description": "", "text": "-enable-pretty-printing", "ignoreFailures": true } ]
        }
    ],
    "compounds": []
}

And there, you’re done. Now you can run Blender from inside Visual Studio Code by hitting F5. If you selected a Debug build type, breakpoints will work as excepted, etc.

Conclusion

It was my first time using Visual Studio Code, and I must say I’m very impressed by the ease of use and feature set ! Out of the box, it has Git support, and through the embedded extension manager you can enable C/C++ building/debugging/etc., CMake support, etc. with only a few clicks !

And then the setup part is completely straightforward ! You have a .vscode folder in your project containing the various .json setting files, and in each of those files, autocompletion works like a charm so you can easily find what you want, without even having to bother looking online for documentation / help !! (in my first tests, I was on an old computer where I had to specify the path to my custom CMake, and the path to my custom GDB, and I found them in a few seconds without having to leave the IDE)

Anyway, I highly recommend you to give a try to this software, CMake support is almost perfect (I still have to delete the build folder manually whenever I want to change the options CMake was configured with, but other than that, perfect) and building / debugging is fast, intuitive, user friendly and powerful.

Change default location of Visual Studio’s intellisense databases

A small post-it on how to change the default location of intellisense databases for Visual Studio. By default, those huge .sdf files (which get updated again and again) are stored next to your project location.

If you’re working on an SSD, or on a slow USB drive, you might want to avoid storing those databases at their usual location (or just to avoid having huge files around, or whatever other reason)

To do that, just go to Tools > Options then on the Text Editor > C/C++ > Advanced tab, locate the section Fallback Location. Here, Always use Fallback Location will need to be set to true to tell Visual Studio to always use the Fallback Location (which you can then set to any folder you want, or leave empty if you want to use the windows temp folder)

You can now close Visual Studio, remove your sdf files, launch it again. It will prompt you about your fallback location, but you just have to click OK and don’t forget to check the Don’t Prompt Me Again checkbox to avoid this at every launch. Tadaaa, no more sdf files next to your projects !

[Source]

Compiling ICU with Visual Studio 2013

In my previous post on how to build Qt on Windows, I explained how to build Qt for Windows, using Visual Studio 2010 and prebuilt ICU libraries. If we want to build Qt with Visual Studio 2013, we’ll need to build ICU ourself, and here’s how :

  • Download ICU sources from here : http://site.icu-project.org/download
  • Unzip in C:\ (you will have a C:\icu folder with C:\icu\readme.html (among others))
  • Go into C:\icu\source\common\unicode, edit platform.h and add the following somewhere at the beginning. It’s needed if you want to build Qt :
#define U_CHARSET_IS_UTF8 1
  • Go into C:\icu and create a build.bat file, with the following content and run it :
@echo off

::
:: setup Visual Studio 2013 environment for x64 builds
::
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64

::
:: build
::
msbuild source\allinone\allinone.sln /m /target:Build /property:Configuration=Release;Platform=x64
msbuild source\allinone\allinone.sln /m /target:Build /property:Configuration=Debug;Platform=x64

This will build ICU in x64. You can run the same script again and remove the “x86_amd64” argument to the vcvarsall.bat script, and change the Platform property to Win32 to build ICU in x86.

Building Qt from sources on Windows

Building Qt is not in itself difficult. But building Qt on Windows, and with QtWebkit can become quite the challenge. So here is a little tutorial on how I did it.

Configuration

First of all, you’ll need a lot of stuff correctly installed. Keep in mind that the paths to the following tools should appear in your PATH env var. Some installers will update it for you, for others you’ll need to add it personally.

So the first thing you’ll want to install is this great tool : Rapid Env Editor. Be careful though, the big Download button on the download page is NOT the one you want to click ! You don’t have to go to the download section, you have download links in the header on the upper right :) (I made the mistake, thus this warning)

Now the list of stuff you to install :

Now, time to get the sources / libraries :

  • Qt (Get the source zip)
  • ICU (Get the package corresponding to your compiler. Currently only Visual Studio 2010, you’ll need to build from sources to get a version corresponding to Visual Studio 2013)

Extract Qt and ICU somewhere on your disk. I recommend you to put that in a short path, such as C:\Qt and C:\ICU. See Troobleshooting section for the reason why :)

Building

Once everything’s installed and the paths to the tools in your PATH env var, you’re ready to build.

Go into the Qt sources root folder, then create a file name build_Qt_x64.bat (for instance) and copy the following into it :

@echo off

::
:: Remember the source path (where the Qt sources are, e.g. where this file is)
::
set sourcepath=%cd%

::
:: The following part should be updated to reflect your build environment
::

:: this will setup Visual Studio so that we can use it in command line
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86_amd64

:: where we want to install Qt
set installpath=C:\Qt_x64

:: set the path where icu's lib was installed
set icupath=C:\icu
set icusuffix=64

::
:: Setup the configuration
::

set configuration= -opensource -confirm-license -debug-and-release
set configuration= %configuration% -prefix "%installpath%"
set configuration= %configuration% -c++11 -mp -opengl desktop
set configuration= %configuration% -icu -I "%icupath%\include" -L "%icupath%\lib%icusuffix%"
set configuration= %configuration% -no-compile-examples -nomake tests -nomake examples -no-accessibility
set configuration= %configuration% -skip qtwebkit-examples

::
:: Cleanup previous install
::

if exist "%installpath%" ( echo Removing "%installpath%" )
if exist "%installpath%" ( rmdir /Q /S "%installpath%" )
if not exist "%installpath%" ( echo Creating "%installpath%" )
if not exist "%installpath%" ( mkdir "%installpath%" )

::
:: Update the path with a few access to dlls, tools, etc.
::

set path=%installpath%\qtbase\lib;%path%
set path=%icupath%\bin%icusuffix%;%path%
set path=%sourcepath%\GnuWin32\bin;%path%

::
:: Configure.
::

pushd "%installpath%"
call "%sourcepath%\configure" %configuration% -platform win32-msvc2010

::
:: And build
::

nmake
nmake install
nmake clean

popd

Now you can build by opening a command line on the root folder, and by typing the following :

build_Qt_x64.bat
nmake
nmake install
nmake clean

The first line is quite fast (a few minutes) and the second can take a whole night :) The 2 last are quite long too, but it’s reasonable (a few hours max)

Troubleshooting

Hopefully everything will work well, but here are a few problems that you might encounter. I’ll update this part if needed.

fatal error U1095

One of the compilation command line is too long. The solution (which worked for me) is to ove the Qt and ICU to short folders, such as (for instance) C:\Qt and C:\ICU

fatal error U1077

This has to do with ICU. You shouldn’t get this if you’re building with Visual Studio 2010. If you’re using Visual Studio 2012 or 2013, see this post about building ICU (thanks Mihai :p)

Release x64 crashes when all other versions work

This one I discovered very recently, and updated the build script. It’s due to a bug in the Visual Studio 2010 compiler for x64, when you use link time code generation (the -ltcg option) So the solution is to not use this option :)

References

Scope based execution of arbitrary code with C++11

Imagine the following peace of code (which is really simple for the sake of the example :)

for (entity in entities)
{
    glPushMatrix();

    // do some stuff

    glPopMatrix();
}

The basic idea here is that you need to maintain the integrity of a states’ stack in a loop. But what happens if you have some tests that allow to break, continue or return :

for (entity in entities)
{
    glPushMatrix();

    // do some stuff

    if (entity->NeedToDoOtherStuff() == false)
    {
        continue;
    }

    // do some other stuff

    glPopMatrix();
}

Wrong. You didn’t pop the matrix, everything gets corrupted. You need to add a glPopMatrix() right before continue. And the more of those special cases, the more glPopMatrix you need to add. And if you have more states to push / pop, you need to duplicate those too.

This scenario happens a lot in real applications. If you allocate some temporary data to work with, you need to cleanup before exiting the function, and if you have many exit points (error checks, etc.) you end up duplicating cleanup code everywhere, which is error prone and fastidious. You can also use goto’s :)

Here is a little templated class which solves this problem using 2 features of C++11 : lambdas and functional.

class Cleanup
{
public:
    template< typename T >
    inline Cleanup(T && code)
        : m_Code(code)
    {
    }

    inline ~Cleanup(void)
    {
        m_Code();
    }

private:
    std::function< void (void) > m_Code;
};

This class can be used like this :

for (entity in entities)
{
    glPushMatrix();
    Cleanup popMatrix([]() { glPopMatrix(); });

    // do your stuff
    // make some tests, continue or break depending on the reults
    // do other stuff
}

As soon as the Cleanup instance goes out of scope it will execute the code that you gave it. I find this particularly useful :

  • no longer crashes when you add an exit point, special case, etc. and forget to copy / paste the cleanup code.
  • the cleanup code is defined right at the top of the scope, which in my experience makes it really hard to forget updating it, if you need to add more states, more intermediate data that need cleanup, etc.

Userfriendly Qt5 Types in Visual Studio Debugger

If you’re using Visual Studio 2012 or 2013 Express with Qt, you can’t use the Qt Addin, but you might still want to have user friendly Qt types showing in your debugger. Luckily this is quite easily achieved :

  1. Download the qt5.natvis file from the Qt Git repository.
  2. Make sure you have the following folder : <MyDocuments>\Visual Studio 2013\Visualizers and if not, create it.
  3. Copy the qt5.natvis file in it, and restart Visual Studio.
  4. Done.

Build boost as static libs for Visual Studio 2012

Following is a small script that I use to build a few static Boost libraries in 64 bits for Visual Studio 2012, and with iterator debugging turned off.

:: build the bjam and b2 exe
if not exist "b2.exe" (
    bootstrap.bat
)

:: build boost with visual 2012 toolset.
::   - static lib
::   - multithreaded shared runtime
::
:: it only builds signals and filesystem
b2.exe -a -d0 -j4 toolset=msvc-11.0 address-model=64 variant=debug link=static threading=multi runtime-link=shared define=_HAS_ITERATOR_DEBUGGING=0 --with-signals --with-filesystem
b2.exe -a -d0 -j4 toolset=msvc-11.0 address-model=64 variant=release link=static threading=multi runtime-link=shared define=_HAS_ITERATOR_DEBUGGING=0 --with-signals --with-filesystem

Multiple commands in Sublime Build System

A little note on the build system integrated in Sublime. If you have multiple commands to execute during a build (for instance minifying your js code, and generating the documentation) your can do it quite easily on Windows, but it took me a while to find the equivalent on Mac, so here is the relevent (simplified version) part of my build system:

"windows": {
    "shell": true,
    "cmd": [
        "python", "build.py", "compress", "&;"
        "python", "build.py", "doc"
    ]
},
"osx": {
    "shell": false,
    "cmd": [
        "sh", "-c", "python build.py compress && python build.py doc"
    ]
}

Notice the difference between Windows and OSX. On Windows, you simply add an additional “&;” parameter which will separate the commands, but on OSX (I guess it would be the same on Linux) it doesn’t work. The only way I found to execute multiple commands was to directly call sh with the -c option and put all my commands in a single string. The commands are then separated by a && sequence.

Oh and also shell must be true on Windows, but false on OSX, else nothing runs.