Deep CMake for Library Authors - Craig Scott - CppCon 2019
HTML-код
- Опубликовано: 9 сен 2024
- CppCon.org
-
Discussion & Comments: / cpp
-
Presentation Slides, PDFs, Source Code and other presenter materials are available at: github.com/Cpp...
-
This talk presents a road map for C++ library authors grappling with cross-platform aspects of library development and deployment. It highlights key CMake features that every cross-platform library project should be using and digs deeper into the platform-specific quirks and conventions behind them. The material presented will give library authors more robust control over their API, smoother integration with major platforms and packaging systems, and more convenient inclusion by other projects.
The presentation will firstly examine how symbol visibility, library versioning and API evolution can be handled coherently across all major platforms and compilers. CMake provides dedicated features for these that are easy to use, but with the deeper understanding provided by this talk, library authors will be able to make these areas work together more seamlessly and avoid future maintenance and compatibility issues.
We will then explore how platform and vendor differences affect the installed directory layout for projects with libraries. CMake features for transparently handling the different conventions and policies will be presented, including recent CMake improvements which simplify this task. The importance of RPATH/RUNPATH functionality for improved runtime robustness and ease of use will also be explained, along with some associated support CMake provides.
Along the way, the talk will mention a number of specific things that CMake library projects should do or avoid to make themselves easy for other projects to consume. This will include versioning support for CMake config package files, guidance on defining install components and accounting for the different ways that projects may incorporate yours into their build.
-
Craig Scott
Crascit Pty Ltd
Founder
Craig is a CMake co-maintainer and author of the book “Professional CMake: A Practical Guide”. He has been developing cross-platform C++ software since 2001, targeting most major platforms and working on large scale frameworks, scientific algorithm development, Qt GUI applications, backend services and embedded devices. He is the company founder of Crascit Pty Ltd, through which he offers consulting services related to CMake, C++ and build/release processes.
-
Videos Filmed & Edited by Bash Films: www.BashFilms.com
*-----*
Register Now For CppCon 2022: cppcon.org/reg...
*-----*
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.
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
nice finally some in depth information how to package stuff correctly
I wish you had a youtube channel I could subscribe to, excellent talk
This is freaking great stuff!
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).