{"id":952,"date":"2019-06-28T13:57:01","date_gmt":"2019-06-28T11:57:01","guid":{"rendered":"https:\/\/www.scionova.com\/?p=952"},"modified":"2020-06-08T17:48:37","modified_gmt":"2020-06-08T15:48:37","slug":"why-not-not-modern-cmake","status":"publish","type":"post","link":"https:\/\/www.scionova.com\/en\/why-not-not-modern-cmake\/","title":{"rendered":"Why not not Modern CMake"},"content":{"rendered":"<p><strong>Lately I have worked a lot with the build framework\/system in the project of my current assignment in automotive. Doing so I have noticed the benefit of writing CMake conforming with what is called &#8216;Modern CMake&#8217;, or rather the draw backs of not doing it. Therefore, I&#8217;d like to take the opportunity to share my experience.\u00a0<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p><span data-contrast=\"auto\">This will not be a complete description of what Modern <\/span><span data-contrast=\"auto\">CMake<\/span><span data-contrast=\"auto\"> is, there are loads of articles about that, and <\/span><a href=\"https:\/\/cliutils.gitlab.io\/modern-cmake\/\"><span data-contrast=\"auto\">here is a good entry point to Modern <\/span><span data-contrast=\"auto\">CMake<\/span><\/a><span data-contrast=\"auto\">. However, I&#8217;ll give you a few Do&#8217;s and Don&#8217;ts along with the issues I had when these were not followed. But my main advice is to think of <\/span><span data-contrast=\"auto\">CMake<\/span><span data-contrast=\"auto\"> as any other production code and demand quality, readability and maintainability.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Do <\/span><span data-contrast=\"auto\">not <\/span><span data-contrast=\"auto\">use global functions such as <\/span><span data-contrast=\"auto\">include_directories<\/span><span data-contrast=\"auto\"> or <\/span><span data-contrast=\"auto\">link_libraries<\/span><span data-contrast=\"auto\">. These often shroud what targets <\/span><span data-contrast=\"auto\">actually use<\/span><span data-contrast=\"auto\"> and need. Use functions<\/span> <span data-contrast=\"auto\">as<\/span> <span data-contrast=\"auto\">target_include_directories<\/span><span data-contrast=\"auto\"> and <\/span><span data-contrast=\"auto\">target_link_libraries<\/span><span data-contrast=\"auto\"> to modify each target explicitly instead.<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"2\" data-aria-level=\"1\"><span data-contrast=\"auto\">Do <\/span><span data-contrast=\"auto\">not<\/span><span data-contrast=\"auto\"> modify the <\/span><span data-contrast=\"auto\">CMAKE_CXX_FLAGS<\/span><span data-contrast=\"auto\"> in subprojects. The project might change to a compiler that do not support all the flags the old did. This kind of variable should be modified on the top level CMakeLists.txt or preferably in a <\/span><a href=\"https:\/\/cmake.org\/cmake\/help\/v3.15\/manual\/cmake-toolchains.7.html\"><span data-contrast=\"auto\">toolchain file<\/span><\/a><span data-contrast=\"auto\">.<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Use <\/span><span data-contrast=\"auto\">ALIAS<\/span><span data-contrast=\"auto\"> targets so that <\/span><span data-contrast=\"auto\">add_subdirectory<\/span><span data-contrast=\"auto\"> and <\/span><span data-contrast=\"auto\">find_package<\/span><span data-contrast=\"auto\"> exports the same name for targets. The issue I saw in my current project was when we started to build an external library instead of using <\/span><span data-contrast=\"auto\">prebuil<\/span><span data-contrast=\"auto\">d<\/span><span data-contrast=\"auto\">s<\/span><span data-contrast=\"auto\"> (or vice versa), and the <\/span><span data-contrast=\"auto\">target_link_libraries<\/span><span data-contrast=\"auto\"> of all the dependent components needed to be updated.<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"2\" data-aria-level=\"1\"><span data-contrast=\"auto\">Do<\/span> <span data-contrast=\"auto\">n<\/span><span data-contrast=\"auto\">o<\/span><span data-contrast=\"auto\">t use <\/span><span data-contrast=\"auto\">target_inlude_directories<\/span><span data-contrast=\"auto\"> with paths reaching outside the directory of the component. The project might change its file structure and all these paths need to be updated. Instead, export the needed header files from the other component, either with <\/span><span data-contrast=\"auto\">target_include_directories<\/span> <span data-contrast=\"auto\">with <\/span><span data-contrast=\"auto\">PUBLIC<\/span><span data-contrast=\"auto\"> properties or simply export an <\/span><span data-contrast=\"auto\">INTERFACE<\/span><span data-contrast=\"auto\"> library.<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"3\" data-aria-level=\"1\"><span data-contrast=\"auto\">Provide well defined and documented functions for adding tests on a project level. The main benefit is that <\/span><span data-contrast=\"auto\">it<\/span><span data-contrast=\"auto\"> is easier to change the <\/span><span data-contrast=\"auto\">behaviour<\/span><span data-contrast=\"auto\"> of the tests and how they are used in CI Gates if <\/span><span data-contrast=\"auto\">n<\/span><span data-contrast=\"auto\">aming<\/span><span data-contrast=\"auto\"> conventions and label use are centrally enforced\/implemented once.<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"4\" data-aria-level=\"1\"><span data-contrast=\"auto\">Use <\/span><span data-contrast=\"auto\">cmake_parse_arguments<\/span><span data-contrast=\"auto\"> when implementing custom functions. Implementing the same functionality<\/span><span data-contrast=\"auto\">,<\/span><span data-contrast=\"auto\"> yourself might introduce unnecessary complexity or obscurity.<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"1\" aria-setsize=\"-1\" data-aria-posinset=\"5\" data-aria-level=\"1\"><span data-contrast=\"auto\">Do <\/span><span data-contrast=\"auto\">not<\/span><span data-contrast=\"auto\"> overdo the use of variables. When debugging <\/span><span data-contrast=\"auto\">CMake<\/span><span data-contrast=\"auto\"> and\/or the binaries, it might prove challenging to expand all the variables in your head.<\/span><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<p aria-level=\"2\"><strong>Further Reading\u00a0<\/strong><\/p>\n<p><span data-contrast=\"auto\">\u00a0As I mentioned before, there a multitude of articles about Modern <\/span><span data-contrast=\"auto\">CMake<\/span><span data-contrast=\"auto\"> and how to follow it, and here are some of them:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/p>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><a href=\"https:\/\/gist.github.com\/mbinna\/c61dbb39bca0e4fb7d1f73b0d66a4fd1\"><span data-contrast=\"none\">Effective Modern CMake<\/span><\/a><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" aria-setsize=\"-1\" data-aria-posinset=\"2\" data-aria-level=\"1\"><a href=\"https:\/\/cliutils.gitlab.io\/modern-cmake\/\"><span data-contrast=\"none\">An Introduction to Modern CMake<\/span><\/a><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" aria-setsize=\"-1\" data-aria-posinset=\"3\" data-aria-level=\"1\"><a href=\"https:\/\/pabloariasal.github.io\/2018\/02\/19\/its-time-to-do-cmake-right\/\"><span data-contrast=\"none\">It&#8217;s Time to Do CMake Right<\/span><\/a><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" aria-setsize=\"-1\" data-aria-posinset=\"1\" data-aria-level=\"1\"><a href=\"https:\/\/www.youtube.com\/watch?v=y7ndUhdQuU8&amp;feature=youtu.be\"><span data-contrast=\"none\">More Modern CMake<\/span><\/a><span data-ccp-props=\"{&quot;134233279&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\">\u00a0<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Hope you enjoyed my blog post!<\/p>\n<p>&nbsp;<\/p>\n<p>Best Regards,<\/p>\n<p>Patrik Ingmarsson<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-medium wp-image-342\" src=\"https:\/\/scionova.evdy.se\/wp-content\/uploads\/2018\/08\/Patrik.3-225x300.jpg\" alt=\"\" width=\"225\" height=\"300\" srcset=\"https:\/\/www.scionova.com\/wp-content\/uploads\/2018\/08\/Patrik.3-225x300.jpg 225w, https:\/\/www.scionova.com\/wp-content\/uploads\/2018\/08\/Patrik.3-768x1024.jpg 768w\" sizes=\"(max-width: 225px) 100vw, 225px\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lately I have worked a lot with the build framework\/system in the project of my current assignment in automotive. Doing so I have noticed the benefit of writing CMake conforming with what is called &#8216;Modern CMake&#8217;, or rather the draw backs of not doing it. Therefore, I&#8217;d like to take the opportunity to share my [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":""},"categories":[7],"tags":[],"_links":{"self":[{"href":"https:\/\/www.scionova.com\/en\/wp-json\/wp\/v2\/posts\/952"}],"collection":[{"href":"https:\/\/www.scionova.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.scionova.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.scionova.com\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.scionova.com\/en\/wp-json\/wp\/v2\/comments?post=952"}],"version-history":[{"count":0,"href":"https:\/\/www.scionova.com\/en\/wp-json\/wp\/v2\/posts\/952\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.scionova.com\/en\/wp-json\/wp\/v2\/media?parent=952"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.scionova.com\/en\/wp-json\/wp\/v2\/categories?post=952"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.scionova.com\/en\/wp-json\/wp\/v2\/tags?post=952"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}