CMake - the essential package

แชร์
ฝัง
  • เผยแพร่เมื่อ 22 พ.ค. 2024
  • In this video we talk about *CMake*, one of the most used build generation tools. It allows us to have a readable but comprehensive script for our build. Chances are if you look for a random open source project it will support CMake out of the box. We don't cover everything there is about CMake, but pretty much cover most of the important things.
    🎓 Slides: github.com/cpp-for-yourself/s...
    Related materials
    - An amazing CMake tutorial from which lots of inspiration was drawn: cliutils.gitlab.io/modern-cmake/
    - Official CMake website: cmake.org
    Support Ukraine 🇺🇦
    Ukraine is fighting a war against unprovoked russian aggression. Please donate to one of the funds to support them: www.defendukraine.org/donate
    Please support my free work 😉🙏
    - Through Patreon: / code_for_yourself
    - Through GitHub Sponsors: github.com/sponsors/niosus
    Stock footage of the dominos clip provided by Videvo, downloaded from videvo.net
    Contents
    00:00 - Intro
    00:41 - What is CMake
    01:39 - Intuition behind CMake
    02:40 - CMake is just a scripting language
    03:32 - Minimal CMake project
    04:51 - Explaining what CMake actually does
    06:15 - Printing messages in CMake
    06:54 - Building a CMake project with cmake command
    08:57 - Looking at the cache manually
    09:44 - Using ccmake to build the project
    11:33 - Using FORCE with variables
    12:16 - Using INTERNAL keyword with variables
    12:42 - Setting local variables
    13:12 - Adding a library with CMake
    14:52 - Add executables with CMake
    15:07 - Setting target properties with CMake
    16:40 - Dependencies between targets
    17:52 - What target properties can we set
    18:35 - When to use which visibility
    19:21 - Example CMake project
    27:09 - Outro

ความคิดเห็น • 32

  • @CodeForYourself
    @CodeForYourself  ปีที่แล้ว +3

    Anything missing from what you would like to know about CMake? Anything still unclear? Chat with me about it here and I’ll try to add/fix anything we uncover! 😅

    • @strangler_xD
      @strangler_xD 2 หลายเดือนก่อน +1

      I'd like to say THANK YOU for this video. It was only after watching it, that the key concepts of CMake clicked into my head :D.
      I would like to ask though, why do you include the "tools.h" as:
      #include
      I kinda get using instead of "", cause we made a library out of it (right?), but is there a way that we don't have to specify the whole path to the include, but rather use only the name of the include (i.e. #include )?

    • @CodeForYourself
      @CodeForYourself  2 หลายเดือนก่อน

      @@strangler_xD thanks for the praise! 🙌 Glad you found the explanation intuitive enough.
      As for the includes. The vs “” is not really that important and is more or less a convention. They would both work in our case. Now as for the path. We _want_ the path to be longer and to include the folders. The reason for this is that there might be many tools.h files in our project. We want to be sure we use the correct one. Having a full project-specific path removes a possibility to include the wrong include. Does this make sense?

    • @strangler_xD
      @strangler_xD 2 หลายเดือนก่อน

      @@CodeForYourself Hi, thanks for the reply.
      Ok, so it's just making sure that a specific file is chosen.
      If we were to add target_include_directories(tools ${PROJECT_SOURCE_DIR}/our_project/tools/) to the tools' CMakeLists.txt, then we should be able to include as '#include "tools.h"', and still build successfully, right?
      I'm thinking of a use-case where I want to have multiple "tools" all compatible with an application, and build different executables with a different underlying "tools" library, all by changing only the file I include in my project (I think this can be easily manipulated with CMakePresets), hence my questions.
      With the full path in the #include directive I would have to change the source every time I want to build.
      But I guess another way is to always include the same tools.h which would be a "wrapper", and then in that tools.h I conditinally include the actual underlying tools.h path that I want to do (condition being set by a -D command when invoking the build). That way I could keep the absolute path in #include, and not have to invoke target_include_directories() in any of the CMakeLists.txt files.
      Vis-a-vis scalability and maintenance, what would you deem the preferred approach here?

    • @CodeForYourself
      @CodeForYourself  2 หลายเดือนก่อน

      @@strangler_xD to the first part of your comment - yes, if you change the path to target_include_directories as shown then you should be able to include tools.h with just its name.
      As for the use-case you suggest, when would you want to do that? In my experience you never want to confuse different files with the same name. These things are hard to debug and probably won't work how you imagine them to. So, while technically possible, I don't think there are many situations where you'd want to do that. The only use-cases I could think of is when using some compiler-specific libraries and including the fallback otherwise. But in this case, we should just set some macro propagated from CMake and use that for choose which include to pick. Does this make sense?

  • @vinniciusrosa8284
    @vinniciusrosa8284 4 หลายเดือนก่อน +1

    05:34 The best way to explain things. Great content! Thanks so much!

  • @ishi_nomi
    @ishi_nomi 5 หลายเดือนก่อน +2

    Great video! This is what I will share if my teammate need cmake tutorial

    • @CodeForYourself
      @CodeForYourself  5 หลายเดือนก่อน

      Glad you enjoyed it, tell me how it goes ;)

  • @alib5503
    @alib5503 ปีที่แล้ว +1

    Thank you!

  • @theintjengineer
    @theintjengineer ปีที่แล้ว +4

    This video is how I found your channel and you just got a like + sub.
    Man, you were born to teach.
    Even Kitware couldn't make such a good Intro to CMake.
    If you do follow up with CMake Installation Command videos, GTest, CTest, etc... your channel will be the best C++ Channel on TH-cam. Maybe in a separate playlist, since this may not be Beginner C++.

    • @CodeForYourself
      @CodeForYourself  ปีที่แล้ว +2

      Thanks man! Glad to hear that you like it! It did take a couple of, well, takes to record it and it's still not perfect but maybe I will improve it further some time in the future. Do spread the word about it 😉
      The plan for the next video is exactly what you're saying: hot to include google testing into the project and use it with CMake 😬
      This is also not really a beginner C++ course. It just starts with simpler things 😉 it will become more advanced with time.

  • @MrCynosure4sure
    @MrCynosure4sure ปีที่แล้ว +1

    Very informative video. Followed your previous course at UBonn years ago and it is so nice to refresh old concepts again. Thank you for your work.

  • @reverseila4363
    @reverseila4363 ปีที่แล้ว +1

    If you omit the LANGUAGES in the project() command, It will be defaulted to C/C++. I believe in this situation CMake will check for compilers of both languages in the system. So I always specify the language unless I'm going to use both.
    About the question at the end: Because before this line we gave 'tools' target those properties "PUBLIC"ly, then the 'print_hello' target automatically "inherits" those properties, and there is no need to relink 'tools' to that interface target.
    And I just forgot to Thank You!

    • @CodeForYourself
      @CodeForYourself  ปีที่แล้ว

      Yep, you're right about the languages. I generally like a more explicit style where things are spelled out and there are as little as possible default values.
      And yep, you've got it about the dependencies question! Good job! 👍
      Thanks for watching!

  • @kexlex5452
    @kexlex5452 ปีที่แล้ว

    Great video. Thank you. Maybe you can ad ccache to cake in follow up video?

    • @kexlex5452
      @kexlex5452 ปีที่แล้ว

      *add

    • @CodeForYourself
      @CodeForYourself  ปีที่แล้ว

      We can definitely talk about ccache too, but I will probably just add it towards the end. I'm trying to cover essential parts first and then talk about the extras. Ccache is definitely an extra for me.

  • @theintjengineer
    @theintjengineer ปีที่แล้ว

    Also, what can you say about ROS? Is that how you did Robotics or did you use other frameworks?
    Another question: Have you done/worked with Accelerated/Parallel Programming or any sort of HPC?
    And sorry for asking so many questions. Your channel is just too good.

    • @CodeForYourself
      @CodeForYourself  ปีที่แล้ว +3

      We might touch upon ROS. I worked with it of course, I even worked for a company that maintains a safety certified fork of ROS2. An alternative would be to use smth like GRPC using Google protobufs as messages.
      As for parallel, I did write a fair amount of high performance parallel code but I'm not a GPU guru if you're asking about that.

  • @zecuse
    @zecuse 3 หลายเดือนก่อน

    cxx_setup is essentially working like a wrapper for our project (or rather library), right? It's sort of just separating some of the boilerplate stuff from the core of our code?

    • @CodeForYourself
      @CodeForYourself  3 หลายเดือนก่อน

      I wouldn’t really call it a wrapper. It is a kind of library-like cmake target just with nothing to be compiled. It is a dummy target to which we can assign certain properties. Does it explain the notion a bit better?

    • @zecuse
      @zecuse 3 หลายเดือนก่อน

      @@CodeForYourself Ya. I've been playing around with my own project. I knew wrapper wasn't the best word to use for this, but everything we do with it is still inherited by the targets we link it to (because of the INTERFACE visibility).
      I have seen the other comment regarding the question at the end of the video regarding not including the cxx_setup in the executable's link which makes it clear that wrapper isn't the best word to use. I thought about likening it to how composition works, but couldn't think of a good noun to describe that. So, wrapper was the next thing to come up.

  • @heel57
    @heel57 2 หลายเดือนก่อน

    Great video - thanks.
    But - the manual editing of the CMakeCache.txt appears to break what I have learned: "don't modify automatically generated files". Why does this not apply here?

    • @CodeForYourself
      @CodeForYourself  2 หลายเดือนก่อน

      Hey there. That’s a very good point. I’m not sure exactly what to say here. My best guess is that this mechanism in cmake exists longer than the principle you quote. That being said, even though the cmake cache was seemingly designed to be edited by hand, I don’t remember the last time I had to do that.

    • @heel57
      @heel57 2 หลายเดือนก่อน +1

      @@CodeForYourself Ok thanks for taking time to answer my question. I am relieved by your answer that it is not a necessary / common thing to do. I could imagine it to be relevant to temporarily try something out - but the change is gone without warning on next cmake.

    • @CodeForYourself
      @CodeForYourself  2 หลายเดือนก่อน

      @@heel57yeah. It is mostly a convenient way to explain why it is there in the first place. I found no other good way to explain cmake cache in an intuitive way.

  • @Haranoi17channel
    @Haranoi17channel ปีที่แล้ว

    About CMAKE_BUILD_TYPE. You said that It should be set by us in every CMake script. I don't believe that's true. Most of the time we want the ability to choose build type by writing.
    cmake --build /build --config=Release/Debug
    Hence we should not FORCE set this variable inside scripts.

    • @CodeForYourself
      @CodeForYourself  ปีที่แล้ว

      Maybe I said it in a wrong way. I meant that CMake expects us to provide the built type on every build. If we forget, I like to set it to release. Of we provide the build type from the command like as you suggest the if statement won't trigger and the build type will remain the one you set from the command line. Does that make sense or am I missing the point?

    • @reverseila4363
      @reverseila4363 ปีที่แล้ว +1

      I believe '--config' only works with multitarget generators (like Visual Studio, XCode, Ninja Multi-Config, ...). However for single configuration generators (Ninja, various types of Makefiles) CMake simply ignores the --config flag and rely on the CMAKE_BUILD_TYPE variable set during the generation step. So If you are, for example, using Makefiles then the you can do the following
      # config+generation
      cmake -DCMake_BUILD_TYPE=Release -S . -B build
      # build
      cmake --build build -j12