Why CMake sucks (2021)
Sorry for length. Here&#x27;s what I just experienced using one of my vendor&#x27;s CMake builds:<p>(Windows)<p>I open a console, make a build directory, and run cmake.exe, which generates MSVC project files. I open these in Visual Studio and already realize there&#x27;s going to be a problem because the target is &quot;Debug x86&quot; even though I passed -DCMAKE_BUILD_TYPE=Release and this would be cross-compiled for Arm Cortex-M. (The vendor should have this in their CMakeLists.txt, so either they had a large misstep during an easy CMake step, CMake is not intuitive enough for use by a large semiconductor firm, or CMake failed to inform MSVC that the target is ARM.)<p>For shits and gigs, I press build. At least a dozen times: Unknown compiler.<p>(I have two different Arm toolchains... one contained in PATH, the other in a standard install directory.)<p>Now... into Configuration Manager, I change the platform to ARM, but the new error is &quot;cannot open include file&quot;. Thanks, CMake... At this point, I can go into Project Properties, manually add the include directory, and proceed with trying to build. Last time I did this, there were more errors and missing files.<p>At some point, it&#x27;s easier to just put all of the files in a single directory, create an .o out of anything that looks compilable, link it against anything that looks like a linker script, and try to compile a binary with all those objects and scripts.<p>-----<p>(WSL)<p>(The Arm toolchain is installed via package manager and is in my path.)<p>Running cmake .. -DCMAKE_BUILD_TYPE=Release (it really is a pain typing that with the shift key held, and it&#x27;s too short for Caps Lock plus I&#x27;ve mapped Caps Lock to a bunch of AHK macros):<p><pre><code>    -Found assembler: &#x2F;usr&#x2F;bin&#x2F;cc
</code></pre>
Alright. Already, this is problematic. For completeness: &quot;make&quot; results in #warning Unsupported Architecture.<p>At this point, I need to know enough about CMake to &quot;create a toolchain file&quot;, according to StackOverflow. So I&#x27;ve done this---manually specifying arm-none-eabi-gcc as my compiler plus a few other possibly correct flags---but honestly, I have no idea, because CMake probably has more possible non-custom flags than mpv!<p><pre><code>    rm -rf build &amp;&amp; mkdir build &amp;&amp; build
    
    cmake ... -DCMAKE_TOOLCHAIN_FILE:PATH=...
</code></pre>
The correct compiler is detected, but I&#x27;m still getting &quot;Unsupported Architecture&quot;. Wat?<p>-----<p>I can run ccmake to try to fish out all the possible settings. When I change each of the tools to arm-none-eabi-*, I can&#x27;t successfully configure (to exit ccmake) because of an error:<p><pre><code>    The C compiler
    
      &quot;&#x2F;usr&#x2F;bin&#x2F;arm-none-eabi-gcc&quot;
    
    is not able to compile a simple test program.
</code></pre>
...and eventually, undefined reference to _exit<p>So, I can probably get this to keep going by passing -k to gmake, but in ccmake (which oddly only sometimes will reset only a few of the previously changed settings, such as CMAKE_VERBOSE_MAKEFILE) I do not find the argument for passing a flag to make, so this is a dead end.<p>-----<p>Alternatively, I can dive into the manufacturer&#x27;s CMakeLists.txt, but it&#x27;s a rabbit hole. The base-level file is short:<p><pre><code>    cmake_min...
    include(Config.cmake)
    enable_language(C ASM)
    project(...)
    include(${CMAKE_CURRENT_LIST_DIR}&#x2F;cmake&#x2F;generated_src.cmake)
</code></pre>
Config.cmake has one line: the path of the toolchain. I try &#x2F;usr&#x2F;bin and repeat. At this point, I wonder if every CMake expert has also deleted and recreated &quot;build&quot; three times by now. (Spoiler: this didn&#x27;t change anything.)<p>Along the other road, the cmake directory contains three cmake files. In one file, arm-none-eabi-gcc is hardcoded as the compiler (along with friends: ranlib, ar, objdump, etc), so the possibility of using armcc seems slim. In the second file, I see the flags that should stop all of the errors, such as -mcpu=cortex-m33 and the CMSIS include path and everything else. However, this isn&#x27;t a standard variable name but something like MFRTOOL_CMAKE_CXX_FLAGS.<p>The manufacturer&#x27;s (Windows-based) tool might clear all this up. Maybe not. But... Everything already exists in plaintext in the project directory to compile, if CMake could put the pieces together. Anyway, why use a CMakeLists.txt at all if you need an external tool? Why not have a better error message if a tool is required?<p>(The answer, of course, is that CMake requires more than cursory learning and---as with any unintuitive language---most users don&#x27;t want to learn more than necessary or more than StackOverflowable. Plus, I can imagine the original CMakeLists.txt developer for this BSP doesn&#x27;t have the resources to dump into getting this working with every Arm compiler on every host OS for every board in their repertoire.)<p>The final cmake file includes all source using GLOB_RECURSE. This tells me that my earlier intuition of moving all source into one directory and compiling &quot;the old way&quot; (a 20-line Makefile) would probably be the least stress and least rabbit holes.<p>-----<p>In the end, I don&#x27;t know if I should blame the vendor, blame CMake, or blame myself and lack of tool knowledge. I DO know that I can throw together a Makefile in under 30 minutes and it will definitely take more than 30 minutes to get CMake to compile in either Windows or Linux.<p>-----<p>If I tell a person, &quot;use the tools around my house plus this book to make an acoustic guitar&quot; and they throw out the book and go straight to the metalworking tools to shape the body, I&#x27;d have serious doubts about their ability as a maker. This theoretical person is how I feel about CMake.<p>I have to explicitly (in a very verbose, clunky, uppercase flag format) tell CMake how to use my (very standard) tools to compile an essentially &quot;hello world&quot; CMSIS package. The author is right. It sucks.