
Reddit C++ – CMake for Small Projects? - olvy0
https://old.reddit.com/r/cpp/comments/bnkxe7/at_what_point_do_i_need_cmake_for_my_c_projects/
======
phaedrus
Here's my experience. This is partly a CMake rant and partly a CLion rant, but
I feel like the issues/confusion with CLion are a reflection of the issues
with CMake.

I've been struggling for months to convert my hobby project from Code::Blocks
to CMake (so I can use CLion IDE).

What I was trying to do should be simple: I want my subdirectories to build as
static libraries, and then link them all with a main.cpp at the top level.

First obstacle: CLion has (or had) no documentation on how to do this, and no
project wizard to create an example project with this structure. No support
for a "workspace/solution" with multiple "projects" like Code::Blocks or
Visual Studio. CLion (appeared to) require one IDE instance per "project". At
that point, why even use an IDE? And how do I link my executable project to my
library project(s)? Might as well use a text editor and terminal, if I have to
alt-tab to switch between projects and have no help managing dependencies
between projects.

Eventually I realize that, although CLion is one instance per (top-level)
"project", that doesn't mean you can't have other _CMake_ projects _if_ they
are in subdirectories. However, once again the CLion docs are no help in
setting this up, and the CMake docs are really confusing.

One of my in-tree 3rd party dependency libraries has its own well-written but
very old CMake build scripts. For another of my in-tree dependencies I cobbled
together a set of CMake scripts by combining ones someone had written for the
different version of the library together with I-don't-understand-this-but-it-
seems-to-work duct tape programming. Cargo cult programming comes to build
scripts.

Of course, I was still using manual paths to the cmake-build directory to get
the linking to work, and I knew this wasn't right. In Visual Studio, I can
just "Add Reference" from one project to another project, where was this
option in CLion / CMake?

It was at this point I got seriously led astray by trusting bloggers writing
about "Modern CMake". Yes, the new CMake imperatives of the form
"target_foo(...)" (replacing just "foo(...)") _are_ an obvious improvement.
That's not what I'm talking about. The trap for the newbie is that many/most
of these blog posts exhort you to structure your libraries as CMake packages.

"Look! You can build a static library, shared library, or even a .deb file
from these! You don't have to write a FindFoo script, CMake find_package will
know how to find your libraries!"

Cue super-complicated (for a CMake newbie, compared to what I actually needed)
set of incantations to make your project subdirectories into CMake packages.
(Still subtly broken because Modern CMake is a moving target which moved on
since the example was created.)

So I wasted a good several months trying to convert my large codebase to this
format. Never could get my CMake scripts working reliably. Remember the third
party in-tree dependencies full of legacy CMake code and my own cargo cult
duct tape? I'd be hard-pressed to separately understand either these or how
CMake package config should work. I definitely couldn't keep both of these in
my head at the same time.

Finally I realized: this is stupid. I'm _not_ authoring Debian packages; my
sub-libraries are only used by this project, not exported. I _can 't_ link
system-installed alternate versions of my open-source library dependencies
(they're not compatible - that's why the right version is in-tree). And I
shouldn't have to "make install" subdirectories of my own source tree before I
build the executable (the only thing which uses them). I just want to Build
All from the source tree.

I realized that all that following "the Right Way" to do CMake had
accomplished for me was to replace hard-coding linker paths with hard-coding a
"find_package" hint path.

Once I realized I was wrong about the Right Way, and after having studied
CMake for a long time without really grokking it, I realized the answer had
been in front of my face: just use "add_subdirectory()" to add each of my
static-library subdirectories / subprojects (instead of all the CMake package
mumbo-jumbo).

My point being (and the relevance of this comment to the linked Reddit thread)
is that it turned out there was a simple way to do a simple thing, but it
needs to be better called-out, both that it exists and when/why you might want
to use it. The problem is that there's not a good on-ramp to the learning
curve that starts with "here's simple ways to do simple things". Instead (when
you Google for help) it comes back a mix of really basic and really advanced
things and (much like git) you have to already know what you're looking for in
order to find it.

