I like that the guy, as a maintainer, could choose to improve cmake, but rather decides to make a buck from how awful cmake is. Gotta respect the hustle I guess
Not sure if I’m just being paranoid, but that DT_RUNPATH seems like it would be bad for security since which library gets loaded is controlled externally via the LD_LIBRARY_PATH environment variable. On the other hand, I understand that this machanism is great for some copyleft libraries, since they want to provide library consumers with ways to replace the versions of the library even within third-party executables (e.g. LGPL v3). That then begs the question: should DT_RUNPATH really be the default when setting the RUNTIME_PATH target property? IIRC, this is the case with CMake since a few months ago (something like 3.27 maybe?).
There's already a proof-of-concept for RPATH support on Windows, but it doesn't seem to have gotten much traction. Unless that situation changes, there's not much CMake can do about the lack of RPATH on that platform. More info here: developercommunity.visualstudio.com/idea/566616/support-rpath-for-binaries-during-development.html Even without RPATH though, there are techniques to allow your tests and executables to run from within the VS IDE without having to put everything in the same directory. It can be a little involved though if you are using older CMake versions. If you have my book "Professional CMake: A Practical Guide", it's covered in section 28.6 "Windows-specific Issues" of the 4th edition, with examples. With CMake 3.13 the VS_DEBUGGER_ENVIRONMENT test property is what you're looking for. You can also set the ENVIRONMENT test property to cover running directly under ctest as well. For older CMake versions, messing around with user properties files can achieve the same effect, but it's much less straightforward.
@@craigscott5548 if his book is as good as this presentation I would buy it for sure!!! Saved me from many headaches... Cmake is lacking from good tutorials, examples for beginners, examples for advanced users. I am struggling it to learn cmake.
@@craigscott5548 What do you recommend for git submodule support? Do you put into lib folder or make custom folder? How would you handle automatic downloading of git submodules? I have seen solutions using execute_process() in the configuration stage. What's you take?
You could use DDL Redirection for versioning, so example.dll would forward everything to example.2.4.7.dll. This is feature that is regularly used in system dlls as things move about and is well documented. Now it's not as slick as a symlink, but the forwarding dll would be small as it would only have import tables. not a perfect solution, but a well supported one.
Why on earth doesn't cmake just do all these things for you instead of you having to be a damn expert in Cmake? If these are best practices, they should be what you get without doing _anything at all_. If you need something more, you should be able to extend the defaults. CMake is so complicated you need a new tool to generate CMakeLists.txt files for you.
Hmmm, part of the difficulty is probably the need to be compatible with previous versions and for me this is the most important thing when it comes to big projects that we need to maintain for years.
I’d guess many of these issues are only really arising nowadays, partly because package management has become increasingly popular. So CMake couldn’t necessarily do everythig right from the start, because nobody could have confidence that they have an accurate understanding of the entire ecosystem, until these more user-transparent package managers came along that is.
Visibility should always be on by default, and if you really need to hide something, which is stupidly rare, then put it in an anonymous namespace. The effect is platform independent and much less work. Why the hell are people using __declspec etc... is there a single good reason?
Strong disagreement. By default, I think you should think very carefully about what is being exposed in your library, and always err on the side of caution (read: hide it). Once something is public, it's incredibly difficult to undo that decision.
The best comment around. No, there is no frigging good reason, other than many amateurs out of the university, that have learnt, from somebody who never actually build anything professionally "Hide! hide all!!!". After all, you are just making things a little bit more difficult, but if somebody really wants to use "hidden"things, they actually can... I suggest using your time writing good documentation, and explaining why *you think* is bad idea to use things you did not intended to, but leave the user the door open. But, never, ever, try to outsmart your user!
Whether hiding should be on or off by default is debatable of course! Both offer pros and cons. The problem is that I don’t recall, with MSVC, ever seeing a way to make everything visible by default (it’s possible that exists and that I just missed it, but I’d guess not). You just *have* to specify the declspec attribute. CMake does have a mechanism to automatically export all functions specifically to cover MSVC (I’ve tried it), but even that still doesn’t export global variables, so you’d still need to add the declspec to the global variables (to all of them, including class-static data members, if you *really* want to export everything).
Excellent presentation. It can save you many hours from reading documentation and debugging cmake problems.
Thank you for this video. I watched this, and a few weeks later needed every last bit of the detail at my job.
nice finally some in depth information how to package stuff correctly
Thanks Craig, i bought your book and learned something from it, but still so many things still unclear. Much better then any tutorial from Kitware.
I like that the guy, as a maintainer, could choose to improve cmake, but rather decides to make a buck from how awful cmake is. Gotta respect the hustle I guess
This is freaking great stuff!
I wish you had a youtube channel I could subscribe to, excellent talk
Not sure if I’m just being paranoid, but that DT_RUNPATH seems like it would be bad for security since which library gets loaded is controlled externally via the LD_LIBRARY_PATH environment variable.
On the other hand, I understand that this machanism is great for some copyleft libraries, since they want to provide library consumers with ways to replace the versions of the library even within third-party executables (e.g. LGPL v3).
That then begs the question: should DT_RUNPATH really be the default when setting the RUNTIME_PATH target property? IIRC, this is the case with CMake since a few months ago (something like 3.27 maybe?).
59:05 The Kitware censors in action!
Mathieu Ropert's question: is there a planned feature to get tests working with rpath on Windows?
There's already a proof-of-concept for RPATH support on Windows, but it doesn't seem to have gotten much traction. Unless that situation changes, there's not much CMake can do about the lack of RPATH on that platform. More info here: developercommunity.visualstudio.com/idea/566616/support-rpath-for-binaries-during-development.html Even without RPATH though, there are techniques to allow your tests and executables to run from within the VS IDE without having to put everything in the same directory. It can be a little involved though if you are using older CMake versions. If you have my book "Professional CMake: A Practical Guide", it's covered in section 28.6 "Windows-specific Issues" of the 4th edition, with examples. With CMake 3.13 the VS_DEBUGGER_ENVIRONMENT test property is what you're looking for. You can also set the ENVIRONMENT test property to cover running directly under ctest as well. For older CMake versions, messing around with user properties files can achieve the same effect, but it's much less straightforward.
Forgot the book link: crascit.com/professional-cmake/
@@craigscott5548 if his book is as good as this presentation I would buy it for sure!!! Saved me from many headaches...
Cmake is lacking from good tutorials, examples for beginners, examples for advanced users. I am struggling it to learn cmake.
@@panagiotisfollas1799 The book is damn fine 👌
@@craigscott5548 What do you recommend for git submodule support? Do you put into lib folder or make custom folder? How would you handle automatic downloading of git submodules? I have seen solutions using execute_process() in the configuration stage. What's you take?
You could use DDL Redirection for versioning, so example.dll would forward everything to example.2.4.7.dll. This is feature that is regularly used in system dlls as things move about and is well documented. Now it's not as slick as a symlink, but the forwarding dll would be small as it would only have import tables. not a perfect solution, but a well supported one.
Why on earth doesn't cmake just do all these things for you instead of you having to be a damn expert in Cmake? If these are best practices, they should be what you get without doing _anything at all_. If you need something more, you should be able to extend the defaults. CMake is so complicated you need a new tool to generate CMakeLists.txt files for you.
CMake is complicated because it is marrying together all the operating systems again that have diverged greatly over the years
Hmmm, part of the difficulty is probably the need to be compatible with previous versions and for me this is the most important thing when it comes to big projects that we need to maintain for years.
I’d guess many of these issues are only really arising nowadays, partly because package management has become increasingly popular. So CMake couldn’t necessarily do everythig right from the start, because nobody could have confidence that they have an accurate understanding of the entire ecosystem, until these more user-transparent package managers came along that is.
Because the presenter wants to sell his book
Visibility should always be on by default, and if you really need to hide something, which is stupidly rare, then put it in an anonymous namespace. The effect is platform independent and much less work. Why the hell are people using __declspec etc... is there a single good reason?
I strongly disagree, everything should be hidden by default for the same reason nothing should be in the global namespace by default
Strong disagreement. By default, I think you should think very carefully about what is being exposed in your library, and always err on the side of caution (read: hide it). Once something is public, it's incredibly difficult to undo that decision.
The best comment around. No, there is no frigging good reason, other than many amateurs out of the university, that have learnt, from somebody who never actually build anything professionally "Hide! hide all!!!". After all, you are just making things a little bit more difficult, but if somebody really wants to use "hidden"things, they actually can... I suggest using your time writing good documentation, and explaining why *you think* is bad idea to use things you did not intended to, but leave the user the door open. But, never, ever, try to outsmart your user!
Whether hiding should be on or off by default is debatable of course! Both offer pros and cons.
The problem is that I don’t recall, with MSVC, ever seeing a way to make everything visible by default (it’s possible that exists and that I just missed it, but I’d guess not). You just *have* to specify the declspec attribute. CMake does have a mechanism to automatically export all functions specifically to cover MSVC (I’ve tried it), but even that still doesn’t export global variables, so you’d still need to add the declspec to the global variables (to all of them, including class-static data members, if you *really* want to export everything).