Debugging CMake Issues
I've been using CMake for many years and our in house C++ library that we use to build interactive systems for conferences, events, startups, etc. makes use of it. The beauty of CMake is that once you've created your CMake scripts setting up your project becomes a very simple task. Also, I like to develop without an IDE like Visual Studio or XCode which is a perfect fit when using CMake from the command line. I'm not going further into the pros and cons because it's mostly about finding the most convenient way that fits you personal needs.
Our library has grown over the years and it can be used for many different projects. It has support for video encoding, decoding, streaming, 3D rendering, serial communication, artnet, osc, touch, gestures, etc. Some of these features need external projects. For a recent project I've been using GStreamer which I wanted to integrate into my CMake scripts but ran into an issue. After spending some time fixing this issue I decided it would be worth to write a blog post as this might be helpfull for you.
CMake provides a feature called External Projects. An external
project can be any other project that you want to include in your
main CMake project. By using add_dependency() you can tell CMake that
your project, for example your library or executable depends on
another target. An external project is a target; so you can tie
them together.
Most external projects are simple to add. You add the
ExternalProject_Add() command, specify the source via URL or
GIT_REPOSITORY, the BUILD_COMMAND, etc. and you're good to go.
Or at least, until you run into an error.
This was exactly the case where I ran into today and wanted to write down a step by step process you can follow to find out what is causing the error and give you hints how to sovle them. The problem I was facing, was that I was building GStreamer as an external project on Windows and the only message I got in the console output which indicated some sort of error was:
The filename, directory name, or volume label syntax is incorrect.
There was no contextual information about what might cause the issue. The command that I used was something like this:
ExternalProject_Add(
gstbuild
GIT_REPOSITORY https://gitlab.freedesktop.org/gstreamer/gst-build.git
GIT_SHALLOW 1
CONFIGURE_COMMAND "meson -Dgst-plugins-ugly:x264=disabled -Ddevtools=disabled build"
BUILD_COMMAND "ninja -C build"
INSTALL_COMMAND "meson install -C build"
)
How to debug your External Project
To figure out what is causing the issue you first want to get more information about what is going on: what command is giving you this error. The external projects are executed as custom build steps and in this particular case I was using Visual Studio 2019 as my build system.
To get a more verbose output you have to look at the options
that your build system provides. You can check the verbosity options for msbuild.exe here.
This meant that I had to add the /verbosity:diagnostic or some
other level during the build command.
CMake allows you to pass custom command line arguments to your build system using two dashes followed by the options;
cmake --build . -- /verbosity:diagnostic /fl
To build my projects I normally create a release.bat and the build command I used
for this particular project looks like the snippet below. Notice that I use ^ to break
lines on Windows; Linux/Mac would use \.
cmake --build . ^
--target gstbuild ^
--config "%cmake_config%" ^
-- /verbosity:diagnostic /fl
I'm using the name of the external project as the
--target. This allows you to only build the external project which means that you don't get any diagnostic information for other projects. Thediagnosticverbosity level gives you -a lot- of information, so having an option to focus on one target reduces the amount of information you have to look into.I've added the
/flflag which generates themsbuild.logfile so can open it in your editor and search through for the error message you get.Open the
msbuild.logand search for yourCONFIGURE_COMMANDor any other command you added to yourExternalProject. In my case I searched formeson -Dgstwhich I found in the logs and looked something like this:cd c:\gstreamer\build\win-x86_64\gstbuild-prefix\src\gstbuild-build if %errorlevel% neq 0 goto :cmEnd C: if %errorlevel% neq 0 goto :cmEnd "meson -Dgst-plugins-ugly:x264=disabled -Ddevtools=disabled build" if %errorlevel% neq 0 goto :cmEnd "C:\Program Files\CMake\bin\cmake.exe" -E touch C:/gstreamer/build/win-x86_64/gstbuild-prefix/src/gstbuild-stamp/Release/gstbuild-configure if %errorlevel% neq 0 goto :cmEnd :cmEnd endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone :cmErrorLevel exit /b %1 :cmDoneTo find the issue you have to look at the details of your specific output. In my case I noticed the
cd c:\gstreamer\build\win-x86_64\gstbuild-prefix\src\gstbuild-buildand the next command:"meson -Dgst-plugins-ugly:x264=disabled -Ddevtools=disabled build". Themeson -Dgst-...command was executed from the wrong directory. Also notice the quotes which shouldn't be used.After finding the cause of the issue, I added
BUILD_IN_SOURCE 1to make sure theCONFIGURE_COMMANDwas executed in the correct directory. I also removed the quotes from all of the other steps.While fixing this issue, I ran into some other errors which were easy to fix by looking at the steps and contents of
msbuild.log.
The final and correct external project command that I used to build GStreamer on Windows looks like:
ExternalProject_Add(
gstbuild
GIT_REPOSITORY https://gitlab.freedesktop.org/gstreamer/gst-build.git
GIT_SHALLOW 1
CONFIGURE_COMMAND meson --prefix=<INSTALL_DIR>/installed -Dgst-plugins-ugly:x264=disabled -Ddevtools=disabled -Dgst-plugins-bad:tests=disabled -Dgst-plugins-good:soup=disabled <INSTALL_DIR>/build
BUILD_COMMAND ninja -C <INSTALL_DIR>/build
UPDATE_COMMAND ""
INSTALL_COMMAND meson install -C <INSTALL_DIR>/build
BUILD_BYPRODUCTS ${gst_byproducts}
BUILD_IN_SOURCE 1
)
NAT Types
Building Cabinets
Compiling GStreamer from source on Windows
Debugging CMake Issues
Dual Boot Arch Linux and Windows 10
Mindset Updated Edition, Carol S. Dweck (Book Notes)
How to setup a self-hosted Unifi NVR with Arch Linux
Blender 2.8 How to use Transparent Textures
Compiling FFmpeg with X264 on Windows 10 using MSVC
Blender 2.8 OpenGL Buffer Exporter
Blender 2.8 Baking lightmaps
Blender 2.8 Tips and Tricks
Setting up a Bluetooth Headset on Arch Linux
Compiling x264 on Windows with MSVC
C/C++ Snippets
Reading Chunks from a Buffer
Handy Bash Commands
Building a zero copy parser
Kalman Filter
Saving pixel data using libpng
Compile Apache, PHP and MySQL on Mac 10.10
Fast Pixel Transfers with Pixel Buffer Objects
High Resolution Timer function in C/C++
Rendering text with Pango, Cairo and Freetype
Fast OpenGL blur shader
Spherical Environment Mapping with OpenGL
Using OpenSSL with memory BIOs
Attributeless Vertex Shader with OpenGL
Circular Image Selector
Decoding H264 and YUV420P playback
Fast Fourier Transform
OpenGL Rim Shader
Rendering The Depth Buffer
Delaunay Triangulation
RapidXML
Git Snippets
Basic Shading With OpenGL
Open Source Libraries For Creative Coding
Bouncing particle effect
OpenGL Instanced Rendering
Mapping a texture on a disc
Download HTML page using CURL
Height Field Simulation on GPU
OpenCV
Some notes on OpenGL
Math
Gists to remember
Reverse SSH
Working Set
Consumer + Producer model with libuv
Parsing binary data
C++ file operation snippets
Importance of blur with image gradients
Real-time oil painting with openGL
x264 encoder
Generative helix with openGL
Mini test with vector field
Protractor gesture recognizer
Hair simulation
Some glitch screenshots
Working on video installation
Generative meshes
Converting video/audio using avconv
Auto start terminal app on mac
Export blender object to simple file format