{"id":92,"date":"2020-01-30T10:55:04","date_gmt":"2020-01-30T08:55:04","guid":{"rendered":"http:\/\/www.juustila.com\/antti\/?p=92"},"modified":"2020-01-31T14:12:43","modified_gmt":"2020-01-31T12:12:43","slug":"using-cmake","status":"publish","type":"post","link":"https:\/\/www.juustila.com\/antti\/2020\/01\/30\/using-cmake\/","title":{"rendered":"Using CMake"},"content":{"rendered":"\n<p>A while ago I was asking in Slack if anyone knew how to write CMake files for C++ projects that work across many platforms, including macOS, Ubuntu and Windows. One said that he has done something multiplatform with CMake, but doesn&#8217;t remember how and added:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>&#8220;I hate tooling in development.&#8221;<\/p><\/blockquote>\n\n\n\n<p>I guess he referred to using CMake. I sort of agree with him but also not. For example, tying yourself in some specific IDE is not very useful. Only knowing how to work with some specific tools not available on many platforms limits the applicability of your skills. Moving to a different ecosystem or platform, requiring different tools will become more difficult and time consuming. <\/p>\n\n\n\n<p>It is better to learn the lower level tools well, those tools which are shared across platforms and ecosystems. Then you can apply and use those wherever you are developing. That is why I prefer using git on command line &#8212; though I do have several git GUI tools installed.<\/p>\n\n\n\n<p>Another thought that came into my mind is that software development without tools just doesn&#8217;t happen. We all use tools, whether it is vim, command line git and makefiles, or CMake, Xcode IDE and Fork for git. I prefer to use the tools that fit the problem. Like, if you are doing development for multiple platforms, with multiple compilers and IDEs, then for solving that problem, CMake is a good choice instead of makefiles. It liberates me from the lower level technical stuff of considering how to create makefiles for different OS&#8217;s and compilers, allowing me to focus on the actual problem to solve with those tools &#8212; creating some code and working systems. <\/p>\n\n\n\n<p>I eventually found the way to create CMake files so that the project I am working on, can be build from the CMake files in Windows 10, Ubuntu and macOS. Also creating projects for Eclipse CDT, Xcode and Visual Studio is quite easy. I can also easily switch from using make to using Ninja as the build engine.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"font-style: italic\"># Creating Ninja build files for a Qt app on macOS from CMake project<\/span>\ncmake -GNinja -DCMAKE_PREFIX_PATH=\/Users\/juustila\/Qt\/5.12.1\/clang_64\/lib\/cmake ..\n<span style=\"font-style: italic\"># Creating MSVC build files on Windows 10 from CMake project<\/span>\ncmake -G<span style=\"font-style: italic\">\"Visual Studio 16\"<\/span> -DCMAKE_PREFIX_PATH=C:<span style=\"font-weight: bold; font-style: italic\">\\Q<\/span>t<span style=\"font-weight: bold; font-style: italic\">\\Q<\/span>t5.14.1<span style=\"font-weight: bold; font-style: italic\">\\5<\/span>.14.1<span style=\"font-weight: bold; font-style: italic\">\\m<\/span>svc2017_64<span style=\"font-weight: bold; font-style: italic\">\\l<\/span>ib<span style=\"font-weight: bold; font-style: italic\">\\c<\/span>make;C:<span style=\"font-weight: bold; font-style: italic\">\\b<\/span>in ..\n<span style=\"font-style: italic\"># Creating Xcode project files on macOS from CMake project<\/span>\ncmake -GXcode -DCMAKE_PREFIX_PATH=\/Users\/juustila\/Qt\/5.12.1\/clang_64\/lib\/cmake ..\n<\/pre><\/div>\n\n\n\n<p>What I learned recently is that it is possible to generate dependency graphs from the CMake project file with GraphViz:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"font-style: italic\"># Create the Xcode project and also a dot file <\/span>\n<span style=\"font-style: italic\"># for generating a dependency graph using GraphViz.<\/span>\ncmake -GXcode --graphviz=StudentPassing.dot ..\ndot -Tpng -oStudentPassing.png StudentPassing.dot\n<\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1019\" height=\"116\" src=\"http:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/StudentPassing.png\" alt=\"\" class=\"wp-image-94\" srcset=\"https:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/StudentPassing.png 1019w, https:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/StudentPassing-300x34.png 300w, https:\/\/www.juustila.com\/antti\/wp-content\/uploads\/2020\/01\/StudentPassing-768x87.png 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>CMake \/ GraphViz generated dependency graph of an app.<\/figcaption><\/figure>\n\n\n\n<p>Resulting in a neat graphical representation of the dependencies of your project. Especially handy if you start working with a large system you do not yet know and want to study what libraries and other components it is built using. And teaching software architecture in practice, as I am currently doing: letting students analyse the structure of a system using available tools.<\/p>\n\n\n\n<p>With CMake, I am able to easily combine document generation with Doxygen into the CMake project:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"font-style: italic\"># In your CMakeLists.txt file:<\/span>\nfind_package(Doxygen)\n<span style=\"font-weight: bold\">if<\/span> (DOXYGEN_FOUND)\n   configure_file( <span style=\"font-weight: bold\">${<\/span>CMAKE_CURRENT_SOURCE_DIR<span style=\"font-weight: bold\">}<\/span>\/doxyfile.in <span style=\"font-weight: bold\">${<\/span>CMAKE_CURRENT_BINARY_DIR<span style=\"font-weight: bold\">}<\/span>\/doxyfile @ONLY)\n   add_custom_target(doc\n      <span style=\"font-weight: bold\">${<\/span>DOXYGEN_EXECUTABLE<span style=\"font-weight: bold\">}<\/span> <span style=\"font-weight: bold\">${<\/span>CMAKE_CURRENT_BINARY_DIR<span style=\"font-weight: bold\">}<\/span>\/Doxyfile\n&nbsp;     WORKING_DIRECTORY <span style=\"font-weight: bold\">${<\/span>CMAKE_CURRENT_BINARY_DIR<span style=\"font-weight: bold\">}<\/span>\n      COMMENT <span style=\"font-style: italic\">\"Generating API documentation with Doxygen\"<\/span> VERBATIM\n   )\nendif(DOXYGEN_FOUND)\n<span style=\"font-style: italic\"># And then generate build files (e.g. for Ninja)<\/span>\ncmake -GNinja ..\n<span style=\"font-style: italic\"># Do the build<\/span>\nninja\n<span style=\"font-style: italic\"># And then generate documentation using Doxygen <\/span>\nninja doc\n<\/pre><\/div>\n\n\n\n<p>I began this post with the question about multi platform development, where my problem originally was how to make all this work in Windows while Ubuntu and macOS was no problem. <\/p>\n\n\n\n<p>For Windows, using CMake required some changes to the CMakeLists.txt project files; using CMake macros with <code>add_definitions()<\/code> due to using random generator engines for Boost uuid class that work differently on Windows than on the other platforms:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if (WIN32)\n   add_definitions(-DBOOST_UUID_RANDOM_PROVIDER_FORCE_WINCRYPT)\nendif(WIN32)<\/code><\/pre>\n\n\n\n<p>Windows also requires some extra steps in the build process, mainly due to the fact that while *nixes have a &#8220;standard&#8221; location for headers and libs (\/usr\/local\/include and \/usr\/local\/lib), in Windows you  should specify with &#8211;prefix (Boost) or -DCMAKE_INSTALL_PREFIX (CMake) where your libraries&#8217; public interface (headers, libs, dlls, cmake config files) should be installed and where they can be found by other components.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A while ago I was asking in Slack if anyone knew how to write CMake files for C++ projects that work across many platforms, including macOS, Ubuntu and Windows. One said that he has done something multiplatform with CMake, but doesn&#8217;t remember how and added: &#8220;I hate tooling in development.&#8221; I guess he referred to &hellip; <a href=\"https:\/\/www.juustila.com\/antti\/2020\/01\/30\/using-cmake\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Using CMake&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[2],"tags":[32,34,36,37,19,35,33],"class_list":["post-92","post","type-post","status-publish","format-standard","hentry","category-coding","tag-cmake","tag-development","tag-dot","tag-doxygen","tag-git","tag-graphviz","tag-multiplatform"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/posts\/92","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/comments?post=92"}],"version-history":[{"count":4,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/posts\/92\/revisions"}],"predecessor-version":[{"id":98,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/posts\/92\/revisions\/98"}],"wp:attachment":[{"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/media?parent=92"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/categories?post=92"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.juustila.com\/antti\/wp-json\/wp\/v2\/tags?post=92"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}