Building from source on Windows with CMake, VS Code, NSIS


The short story is that I needed to install dot for documenting some C++ code on Windows using Doxygen, TeXLive, and CMake. I had some difficulty finding an installer and a coworker was having trouble building from source, so after a short amount of grumbling on Twitter, I committed to looking into what it would take to generate a basic installer (.zip, .msi, setup.exe) for Windows using CMake and CPack.

So far, I’ve been able to pull the Graphviz source and dependencies from gitlab and get CMake to configure everything well enough to build without fatal errors so I’m at the point of seeing what artifacts (binaries, libraries, docs, etc.) have been generated and sorting out where they should be installed under Windows. My main questions are:

  • What files do we need for a basic user installation? (executables, plugins, shared libraries, docs, configs)
  • Is there a notion of a binary developer distribution that avoids building everything from source? (static and dynamic libraries, header files)
  • What would it take to replicate the functionality of the version 2.38 MSI installer?

People suggested I talk with @magjac since he’s also working with CMake and that seems like a really good idea at this point. I’m far more comfortable with linux development than I am with Windows but I spent the last year on cross-platform C++ development using CMake, CTest, and CPack including dependency retrieval and compilation. Assuming my dev setup is properly building things, it shouldn’t take a ton of work to generate a basic Windows installer and later to extend that to various linux distros and potentially OSX.

Thanks for any info you can provide :slight_smile:

Hi @arclight.

Your timing is perfect. None of us maintainers are Windows people so we’ve had some trouble answering questions about it. The binary distribution exists, but is in a sorry state. Rather that just documenting the sorry state, I recently decided to dive into the Windows rabbit hole and improve it and then document it. What I’m doing is moving the builds from to the GitLab CI/CD where we have all the Linux builds. This work is nearly finished and WIP can be found in my local branches (they are nearly the same. Which one is most up-to-date may vary from time to time):

Here are the latest pipelines for each branch:

As a side effect of this work I’ve retargeted the MSBuild project files from Visual Studio 2015 / Windows SDK 8.1 to Visual Studio 2019 / Windows SDK 10.0.

Installing the existing binaries

We build separately with CMake and MSBuild. The CMake builds contain an .exe installer, but the MSBuild builds are just a .zip. I don’t know if the contents is different between them, but I have a hunch (not more than that) that the MSBuild builds are more complete.

  1. Locate a build at
  2. Click on the build you want.
  3. Select configuration by clicking on the job you want to install from
  4. Click on artifacts
  5. Download the .exe and run (CMake) or the .zip and unpack (MSBuild)
  6. Run dot -c to install plugins

Building it yourself

I guess you’ve already seen

You might be helped by looking at:

I don’t think it will add much but here are my “answers” to you direct questions:

I don’t know.

I don’t know, but the MSBuild variants may contain this.

I don’t know. I don’t even know what the difference between an MSI installer and an exe installer is in terms of what they accomplish.

If the above doesn’t make sense, it might be because my Windows experience is less than a month long. Please don’t hesitate to ask follow-up questions. I’ll try to answer to the best of my knowledge.

Thanks for the quick & thorough response! I think my best course of action is to dissect the existing .msi installer and document its contents, then try to replicate that by packaging what CMake currently produces, extending it as necessary. It sounds like I should hold off on looking at the CI/CD setup until it’s been migrated to Gitlab.

FWIW, “I don’t know” is actually a helpful answer here; before I started digging in I wanted to make sure I wasn’t working at cross-purposes. I spend a fair amount of time doing legacy code recovery and revitalization (typically FORTRAN codes from 1970-2000 under linux) and I’ve literally had people drop a file folder containing a floppy disk of source code on my desk with the instruction “make this work”. We’re in better shape than that; I just wanted to make sure I’m actually helping rather than “helping”…

1 Like

I had a working cmake based cross-platform build 8 years ago (Win, Linux, OSX):

But I must confess when I put together a similar build system for the WASM version ( I only built it in WSL on Windows (more for the emscripten stuff than for Graphviz).

I suspect the vcpkgs project will have a lot of the needed dependencies now which might make life easier?

Depending on your use case, there is nothing wrong with just installing graphviz in WSL and calling from windows with: wsl dot --help or similar…

If I get a chance I will try and see how far I can get with a cmake + vcpkgs windows build on the weekend…

1 Like

I went digging through the repo yesterday and made some reasonable progress. NuGet packaging is minimally working; there are warnings about the location of libraries but a nupkg is generated. I believe I have a working WIX packaging setup that preserves the ‘upgrade GUID’ from the previous .msi installer so it should prompt you to uninstall any previous version you may have installed. It all needs external testing; I’ll clean it up and send in a patch/pull request sometime today.

My immediate use case is to support a Doxygen/TeXLive installation on a standard shared Windows build server. I use a heavily customized Doxygen LaTeX template to generate a formal software design spec consistent with the in-house documentation standards (cover page, headers, footers, legal disclaimers and restrictions, review checklists, etc.) Initially I set up everything under Linux but I need to port everything to Windows for production use. Coworkers got stuck following my installation instructions because they couldn’t find the Windows installer for Graphviz (needed for class and call/caller diagrams in Doxygen) and were having a lot of difficulty building it from source. I found the old v2.38 .msi installer and got them going but I was curious why the installer had disappeared and why it hadn’t been updated. One of the devs explained the situation on Twitter and it bothered me because Graphviz has been a really important tool so I committed to looking into improving the packaging on Windows.

Graphviz has been vital in my work in chemical and nuclear safety; we’ve used it to visualize cable routing in nuclear plants for fire risk analysis and to illustrate heat and mass flow models of waste storage facilities and chemical plants. It allows us to review and debug our models and quickly identify broken data in databases and input files. One of our DOE clients built a huge model of their facility’s ventilation system in our code; I had just added DOT output to our code as an experimental feature and sent them a monstrous PDF image of their system topology and didn’t hear from them for a week. Turns out they had printed it out and taped it to the wall, then spent the week looking at it for errors and insight.


@arclight Can you explain to a Windows newbie like myself what the benefit of an .msi installer is compared to the existing Graphviz-install.exe produced by CMake?

Honestly, I don’t know much more than you do at this point. :slight_smile:

Apparently .msi installers can be easier to manage in more centralized environments. An .msi is more like a database than an executable and you have more flexibility in patching, configuring, updating, plus it’s a lot easier to disect and audit than an executable. For an individual user it doesn’t matter much; it’s a convenience for institutional users.

I’m not sure it matters much since NuGet is the shiny new thing in the Windows installer world. FWIW, I’ve been using Chocolatey for local configuration management recently and it mostly abstracts away caring about the specific installer type. It’s nice being able to install and update software on Windows the way Linux has been doing it for the past two decades…

1 Like

Thanks. To me it seems you know a lot more then me :flushed:

What I’m curios about is why you want to make an effort to build an .msi installer instead of just using the existing installer.

I’m also using Chocolatey in the new Windows build pipeline.

Actually win-get is the shiny new thing: