Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for [04/52] MOAR CMAKEZ!
Brian Kirkpatrick
Brian Kirkpatrick

Posted on • Edited on

     

[04/52] MOAR CMAKEZ!

One of the more wonderful things about CMake standardizing C++ codebases is that programs (like scientific tools) that have historically been available only on Linux--at best, with painful support for mediocre toolchains like MinGW--are now accessible to a much wider audience, even if you're building from source.

Today we're going to look at one tool in particular that ends up being a great example of how small and useful tools (like CMake and Visual Studio Build Tools) can be used to build (and even customize!) such programs with relatively little headache.

Some Investigating

Let's look at the toolgmsh. This is a mesh generator that is part of a pretty neat and powerful set of numerical modeling tools with physics applications.

http://gmsh.info/

gmsh

If you go to the website, the first thing that pops out is the fact that they have a GitLab instance linked where development takes place and where the code source is managed. This is a great sign! If you follow that link, you'll find the project page with git-clone addresses, a handy README, release tags, and links to a wiki with excellent build instructions.

https://gitlab.onelab.info/gmsh/gmsh

gmsh gitlab project

The second thing I notice is, there are specific build steps. It mentions the "official" binary releases are built on MinGW, but that doesn't necessarily mean MinGW (or other cross-build tools like WSL) is strictlyneeded. Let's see if we can get away without it.

The other thing you'll notice is that this is part of a suite of tools, "ONELAB". At first I thought this was an organization or laboratory, but it turns out to be a really neat suite of open source numerical modeling tools, and it's worth checking out some of the others.

https://www.onelab.info/

onelab

But let's focus on GMSH for now. From the project page, copy thehttps URL and usegit to clone it locally:

> git clone https://gitlab.onelab.info/gmsh/gmsh.git
Enter fullscreen modeExit fullscreen mode

There are no submodules or other dependencies we need to grab (feel free to verify this yourself). So, now we're ready to open the source and dive in!

Build Tools

JUST KIDDING.

You might need to make sure you have the right tools first. This doesn't necessarily mean waiting for hours to download the Visual Studio IDE, or worry about community licensing restrictions, though. Instead, you can grab every program you need to just run from the command line by downloading the "Visual Studio Build Tools".

https://visualstudio.microsoft.com/downloads/

Scrollaaaaaall the way down and look for the "Download" button under the (as of 2024/02/08)"Tools for Visual Studio" > "
Build Tools for Visual Studio 2022"
section. It's easy to miss, so I've circled it in red below.

visual studio build tools

Once you've installed these tools, you'll see a variety of.BAT files under "V" for "Visual Studio" in your Start menu. These give you the choice of launching cross-platform build environments to, for example, build 64-bit programs from a 32-bit platform (and vice-versa). These are practically useless though--it's 2024, who's building 32-bit programs!? Instead, select the "Native x64" option (again, circled in red).

native x64 build

This launches a command prompt, with a specific environment set up. But you don't want a "special" environment, you want these tools to be available atany point in time! So, let's look at the changes. Specifically, there are three adjustments we need to our user's environmental variables that we can glean from this environment.

First, we need%INCLUDE%. This defines a set of paths where the compiler looks to#include source files and headers. This typically includes a variety of system library paths; without these, you couldn't even build a basic<iostream> program! So, useecho and copy-paste the results into your own version of this environmental variable.

setting include paths

Next, we need%LIB%. This defines a set of paths where the linker (basically the second stage of building a C/C++ program) can find other static libraries with symbols/instructions that the compiler may have assumed would be available by the time the finished product was build. Again, useecho and copy-paste the results into your own version of this environmental variable.

setting lib paths

The last need is a little bit more subtle. You have a%PATH% environmental variable already that tells your system where to look for executables that are invoked. There are several programs you will need to call for our builds to work, roughly organized into three groups:

  • Tools within the build chain, likecl (the compiler) andlink (the linker); these names are specific to Visual Studio, and there are other executables you'll need for other various steps in the build chain, but they're all located in the same place. Usewhere cl to figure out where they were installed, then add the absolute path to your%PATH% environmental variable.

  • We'll also wantcmake itself, which is installed to a different path. CMake configures the build chain, according to the project definition and specific options, before it is "handed off" to a specific "generator" (basically, overseer of build chain tools). Again, usewhere cmake to figure out where it is installed, then add the absolute path to your%PATH% environmental variable.

  • Lastly, we wantmsbuild. This program is like a command-line version of Visual Studio itself--it is responsible for overseeing the build chain that turns a project or solution into a final product. For Windows platforms, this is the "generator" that CMake will use. Like before, usewhere msbuild to figure out where it is installed, then add the absolute path to your%PATH% environmental variable.

exposing tools to your environment

Once you've finished, open up a "fresh" command prompt (WIN+R >cmd) and verify that you can accesscl,cmake, andmsbuild.

verifying paths

Okay.NOW we're ready to dive into the source!

The Source

The first thing we see within our clone is, there's a top-levelCMakeLists.txt file. This is very promising! It means we can go ahead and invoke CMake directly without worrying about other platform-specific tools like Make. Let's give it a shot and see what happens. First, we need to call CMake to set up a build configuration:

> cmake-S.-B build
Enter fullscreen modeExit fullscreen mode

In this case, the-S option tells CMake that the source (effectively, theCMakeLists.txt file) is located in our current folder, and the-B option tells CMake that the "build" folder should be created to store build artifacts. And we see this marches through without any major issues. You can see CMake looking for various build options and dependencies within your environment; it's kind of interesting to see what it checks for.

initial cmake call

Now we can tell CMake to call the "generator" (in our case, Visual Studio, a la themsbuild program) to run through that build configuration.

``sh

cmake --build build
``

This tells CMake to use the build configuration artifacts within the "build" folder to invoke the default generator. And you'll notice pretty soon that there are issues:

FATAL DAMAGE

Oh no! We have to give up!

Not So Fast

If we look at the build messages, we see that the errors are pretty much all related to one specific assumption--that the system can utilize a specific command line option:

...\gmsh\src\geo\GModel.h(260,9): error C7660:'#pragma omp atomic update': requires'-openmp:llvm'commandline option(s)(compilingsourcefile ...\gmsh\src\plugin\VoroMetal.cpp)[...\gmsh\build\gmsh.vcxproj]
Enter fullscreen modeExit fullscreen mode

LLVM is another compiler toolchain, so that's probably not the issue. Instead, let's focus on "OpenMP", which is an advanced message-passing library for high-performance computation. This was never mentioned in the documentation of GMSH's requirements, so it's probably optional. Let's dive into theCMakeLists.txt file and see if there's a way to we can disable or ignore it.

search for openmp

Sure enough, if we search foropenmp we see there's an option defined on line 79. This uses a macro,opt(), so let's look at how that relates to the build. It's defined on line 29.

the opt macro

What we see here is, this macro translates the call into anENABLE_OPENMP (in this case) flag. This defaults to "true", so we want to define it to be "false" instead. Let's look at the CMake options to see how we could do that.

cmake defines

Indeed, we see there's a-D option for setting specific values. Let's call CMake again, but this time assert that wedon't want to enable OpenMP:

> cmake-S.-B build-DENABLE_OPENMP=false
Enter fullscreen modeExit fullscreen mode

After the project is successfully configured, let's try to build it again:

> cmake--build build
Enter fullscreen modeExit fullscreen mode

building, second attempt

Hey, that looks pretty good!

The Program

Take a look at the "build" folder used by CMake to organize our build configuration and artifacts. The specific structure of this folder will change depending on the "generator" you used. For Visual Studio, the typical output location will be under "build/Debug" (debug being the default build configuration, as opposed to "Release").

We can verify what the build outputs should be by searching ourCMakeLists.txt file for theadd_executable directive. Sure enough, there's only one entry point defined for an application (some projects include many), though it can be build with several different conditions. So, we should expect the "default" output to begmsh.exe, build from "Main.cpp" entry point in the source.

gmsh output

And sure enough, if we look under "build/Debug", there it is! Double-click it and see what happens.

waiting for a gmsh gui

Oh no! Is something wrong?

No. What this typically means is, the application was build to be invoked from the command line. We can verify this from the wiki documentation:

https://gitlab.onelab.info/gmsh/gmsh/-/wikis/Gmsh-compilation

how to get the gmsh gui

So, if we want the GUI version/wrapper, we'd need an additional library. This isn't unusual. It's probably not difficult, but we'll leave this as an "exercise to the reader" (or maybe a subsequent article/video). In the meantime, let's invoke the program from the command line and see if it runs.

command line invocation

Hey, it worked! A lot of programs, especially in the space of scientific applications, will use an "empty" invocation as an excuse to tell you how itshould be called, and this is no exception. How do we read this?

In red, I've circled the most important thing--how the command line arguments are structured. Any program has input (sometimes passed viaSTDIN), output (sometimes written toSTDOUT), and maybe a third channel for errors & warnings (likeSTDERR). It's worth familiarizing yourself with these concepts.

https://en.wikipedia.org/wiki/Standard_streams

In this case, we see that the input files are passed to the executable as part of the call. In addition to these channels, you typically have various options you can configure, passed as (for example) flags or key-value pairs. Documenting those takes up the bulk of the "help" we saw printed out.

And that's about it! You should have plenty to get started with some basic use cases for this particular tool. AND, you should have plenty to get started with building many other programs, too--not to mention start developing your own! It's a crazy, wonderful world of C/C++ programming out there, thank goodness (and CMake) that we're reasonable cross-platform in our modern times so everyone can enjoy it with us.

Top comments(3)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
thevnilva profile image
Tori Hevnilva
Fly me high through the starry skiesMaybe to an astral planeCross the highways of fantasy
  • Location
    New Orleans
  • Joined

Honestly, a follow-up on standard streams in different languages/context might be appreciated.

CollapseExpand
 
ebcefeti profile image
E. B. Cefeti
  • Location
    Detroit
  • Work
    Dev and more
  • Joined

Yeah, maybe something a little less esoteric as an example. Maybe evenstart withfltk as an example.

CollapseExpand
 
jocomvag profile image
Jocom Vag
"When done well, software is invisible." -Bjarne Stroustrup
  • Location
    Philadelpha
  • Joined

Okay, maybe CMake might actually be worth some time.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Aerospace engineer with a passion for programming, an intrigue for information theory, and a soft spot for space!
  • Location
    Tustin, California
  • Education
    Harvey Mudd College
  • Work
    Chief Mod/Sim Engineer
  • Joined

More fromBrian Kirkpatrick

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp