9 ms·
I wish there was a good place to learn “the other parts” of C++, the build systems, using static analyzers, testing, dependency management, etc. I’m thinking s
by wirthjason 4y ago
I wish there was a good place to learn “the other parts” of C++, the build systems, using static analyzers, testing, dependency management, etc.
I’m thinking something like MIT’s “missing semester” course which teaches the boots on the ground part of software like how to use Git.
https://missing.csail.mit.edu/ https://missing.csail.mit.edu/
Maybe these resources exist for C++ and I just never found them.
I think a lot of “modern” languages get this right by including these things from the start. The experience is so much better.
- galangalalgol 4y agoFor the build system, I like: http://cliutils.gitlab.io/modern-cmake/ http://cliutils.gitlab.io/modern-cmake/ In addition to building, it will show how to add cppcheck and clang-tidy to your cmake files. That part is pretty easy. Just don't turn on every check in clang-tidy. Many of them are for specific code bases. Modernization checks are my favorite ones. Keeps you doing stuff the modern way. My link has you doing dependency management with git submodules. That is a method still in use and even advocated for, but conan is often touted as the more modern way to do it. I've used it on some teams, and I'm undecided. I also have no good resources for it.
- geokon 4y agoIt's been quite a few years since I've really written any C++ and I'm surprised the landscape hasn't evolved at all. People are making the same mistakes... Modern CMake should be using toolchain files to specify the toolchain/flags. That should be included in ever CMake intro. (Hacking those into your CMakeLists.txt is not okay) gitsubmodules are also a hack 1: Many dependencies are not setup to be used as a CMake subdirectory. Variables such as the project-version-number get overwritten by the parent project and more dangerously the submodule can start to change variables in the overall project. 2: Dependencies will often reuse target names. For instance, libraries often have a target called `uninstall`. Because redeclaring a target in a different subdirectory is a no-no - CMake crashes Proper dependency management can be done directly through CMake without repeating yourself by using Hunter: https://hunter.readthedocs.io/ https://hunter.readthedocs.io/ This solved the diamond problem, gives you proper namespaces in CMake and with Polly you can have sane toolchain files (https://github.com/ruslo/polly https://github.com/ruslo/polly - but you can also just write them manually). Everything is built on CMake and Git (and git hashes). You get nice dependency build caches and forking dependencies is also trivial EDIT: The creator of Hunter has his own CMake Intro. I haven't gone through it while-learning, but it looks comprehensive and informative: https://cgold.readthedocs.io/en/latest/ https://cgold.readthedocs.io/en/latest/
- jcelerier 4y ago> Modern CMake should be using toolchain files to specify the toolchain/flags. That should be included in ever CMake intro. (Hacking those into your CMakeLists.txt is not okay) this so much. I made a toolchain generator to make myself toolchains with common set of flags (asan, lto, etc specified with a single simple word on the command line for each "feature" or at worst a "key=value" pair, e.g. "compiler=gcc", "linker=lld") and really it made my life so much better: https://github.com/jcelerier/cninja https://github.com/jcelerier/cninja
- galangalalgol 4y agoGit submodules are definitely a hack. My experience with conan has been unpleasant for several reasons, but mostly in regards to writing dependencies for code bases that use submodules and aren't interested in my team's suggestion they use conan. Vcpkg doesn't seem better, and probably a bit worse. Does hunter make this any easier?
- geokon 4y agoI'm not super clear what your question is. If the dependency you want to use has no dependencies of its own - then it can be used directly with no changes (as long it's CMakeLists.txt is sane and it can use a passed-in toolchain file) https://hunter.readthedocs.io/en/latest/creating-new/create/cmake.html https://hunter.readthedocs.io/en/latest/creating-new/create/... If the dependency has its own dependencies, then you need to "Hunterize" it - specify library versions, tweak the targets to use namespaces, etc. They're usually small changes. They have a huge list of Hunterized forks: https://hunter.readthedocs.io/en/latest/packages.html https://hunter.readthedocs.io/en/latest/packages.html Finally, a CMakeLists.txt that's been made to work with Hunter can always revert back and be run without Hunter. So the change isn't intrusive. https://hunter.readthedocs.io/en/latest/overview/compatibility.html https://hunter.readthedocs.io/en/latest/overview/compatibili... A minimal CMakelists.txt will look something like: HunterGate( URL "https://github.com/cpp-pm/hunter/archive/v0.23.297.tar.gz" SHA1 "3319fe6a3b08090df7df98dee75134d68e2ef5a3" ) project(Foo) hunter_add_package(Boost COMPONENTS regex system filesystem) find_package(Boost CONFIG REQUIRED regex system filesystem) add_executable(foo foo.cpp) target_link_libraries(foo PUBLIC Boost::regex Boost::system Boost::filesystem) The first block specifies the available package list (you can fork and host your own). If you disable Hunter this isn't used The line that reads `hunter_add_package` is the Hunter part that downloads and build the dependency (using the current toolchain file). But if you disable Hunter then that line would simply get skipped. In the third line `find_package` will run.. and if you had Hunter build the dependency then it'd use that as the target - otherwise it just runs like "normal CMake" and it tries to find the package elsewhere (like from your system package manager or whatever) If your dependency has its own dependencies as git submodules.. then I'm not super sure you have a very clean migration path b/c they will not be using `find_package` and will instead be using `add_subdirectory`. Maybe you could patch their CMakeLists.txt to use Hunter when explicitely enabled, and then drop down to `add_subdirectory` otherwise. It'd be a bit ugly but they would keep their workflow I guess. You'd need to check that their targets end up with the same namespaced names (with the :: notation) when seen from your project... I don't know off the top of my head how Hunter handles a subdirectory with a project name of it's own
- dongping 4y agoHonestly, I find the usage of the adjective "modern" deceptive and insincere in the marketing term "Modern CMake". The "modern" scripting language doesn't even support return values and the variables lack basic type-safety. It breaks for anything beyond a simple Hello World. I would recommend any other C++ build tools that use a proper programming language for scripting, be it Meson or Bazel.
- galangalalgol 4y agoI dislike cmake, so when a sibling post mentioned meson I went looking. It doesn't seem to have good support for cuda, and neither does bazel, to the point I don't immediately find anyone getting it to work. These days the only reason I start a project at work in c++ instead of rust is to use cuda, so that would be a strong consideration. Is this easier than my brief glance would indicate?
- dongping 4y agoI have yet to encounter problems with Cuda in our Bazel environment, but I don't have to maintain the Bazel rules, since our build infra team does that. I would think that rules like https://github.com/liuliu/rules_cuda https://github.com/liuliu/rules_cuda should work for you in Bazel. (Tensorflow also uses Bazel, so I don't think that this should be a problem.)
- Decabytes 4y agoI feel the same way. I remember in one of my failed attempts to learn C++ I had been at it for a few weeks, and was excited to start my own little project in it. I needed to use a piece of software on GitHub and I just could not figure out how to get everything to build. It was a terrible experience that put me off the language.
- eloisius 4y agoPulling in dependencies in C++ when you come from something like Python or Ruby is the absolute worst. I just recently fought through a big mess of this, the gist of it is ExternalProject[1] 1 https://cmake.org/cmake/help/latest/module/ExternalProject.html https://cmake.org/cmake/help/latest/module/ExternalProject.h...
- hoseja 4y ago, which is in a state of active development and doesn't seem to have any good examples/tutorials.
- williamvds 4y agoThis is a good idea. Most modern languages have their own build tool which handle most of these things, so this requires some separate learning with C++. Some ideas for a curriculum: Context - C++ as a standard, compilers as implementations - a build tool's role in handling compilation and linking - compilers having limited abilities, having limited warnings and analysis by default Build tools - evolution: e.g. make -> autotools, cmake, meson - focus on meson as the build tool of choice (personally I'd avoid CMake since it has a lot of legacy baggage) Testing - gtest/gmock - catch - designing for testing Analysis tools - why you should care: security, catching bugs - cranking up built-in compiler warnings to reasonable standards - external tools like clang-tidy, cppcheck - sanitizers: address sanitizer, leak, thread, etc. - fuzzing Dependency management (probably the toughest, since it's still a mess) - history: usually just relying on system packages, or installing libraries globally from source - Conan (probably the best option for simple dependencies that's actually catching on) - CMake external projects, Git submodules - Docker - Nix (if you're feeling adventurous)
- bluGill 4y agoHaving build tools in the language is a negative if you have more than one language in your project has two build tools. Sure it is easier for simple projects, but C++ is not for simple projects.
- MakisH 4y agoIn a C++ course we teach at the Technical University of Munich (for students coming from a non-CS background), this is pretty much the direction we have recently steered the curriculum. It is amazing how we were always expected to "just figure out" all these very important practical aspects by ourselves as students, while these are so complicated for C++. In combination with a lot of outdated material out there, students end up feeling lost and giving up, or going through a lot of pain to develop even simple projects.
- vxNsr 4y agoI always thought the pain was the point. They wanted you to struggle to figure it out, it’s how you learned how to learn. If everything is spoon-fed you end up unable to solve your problems when they arise. You expect someone else to have solved the problem and you start looking for them instead of attempting to solve it yourself. Kinda like the main plot point of Enders game.
- scoutt 4y ago> I think a lot of “modern” languages get this right by including these things from the start. The experience is so much better. I don't know how others did it, but I learned with MS Visual C++ in 1996. File -> New Project -> press F7 to compile, F5 to debug. That's it. ~30 years ago they got it right. I even remember my Windows CE experience ~15 years ago that allowed to build and debug the entire OS from an IDE. Now you have to open your command line and write like it's 1985. Today VS is free (Visual Studio Express?), with analyzers, tests, vcpkg, etc. There is also Qt and other similar tools that I use for embedded like Keil, IAR, Eclipse derivates, etc. C++ != Makefiles. I don't write Makefiles or fiddle with the build system since... ever?. Except for some AOSP stuff that still uses them or perhaps editing some linker script for embedded. PS: that said, "experience" is relative. Having to use the command line in general but mostly for learning is terrible.
- 13of40 4y agoI've always thought it was a little bit pathological that we require application developers to also be experts in build and deployment. The parts that can't be automated away should be handled by (highly paid) specialists so when your dev is deciding whether to make a change they don't have to factor in how it gets from their box to production.
- meindnoch 4y agoAnd then when something goes wrong, you’ll be staring at an opaque .vcproj file without any idea of what’s going on under the hood and how to fix it.
- pjmlp 4y agoFor many kinds of projects, good luck doing it the makefile way (CMake, or whatever one fancies). Yak shaving learning how to use all the compiler and linker flags, and library setup before writing any line of code. Debugging vcproj files is as easy as going down the boilerplate generated by shell scripts and build generators.
- meindnoch 4y ago
- Narann 4y agoConversely, systematically starting a tutorial by listing and briefly explaining the important sections that will not be covered in order to avoid confusions during reading really help newcomers and make them confident.
- bregma 4y agoBuild systems and dependency management are not a part of the language, they're a part of the OS you're developing on (and sometimes for). Or maybe one of several alternatives available for that OS.
- tejohnso 4y ago> “the other parts” of C++ I agree and that would be great. I'd also love a place to learn design with feedback. Should I use a friend function? Free function? Separate class? Abstract class? Should I create a separate folder and start a module? It would be great to have something where you try an implementation, get feedback, and try again maybe a few times and then are presented with a few ideal options that you might not have tried.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]