8 ms·
C++, despite being a really powerful language, has a really primitive build system. Developers have to wade through a complex soup of Makefiles/CMake/Gyp/ninja
by FlyingSnake 9y ago
C++, despite being a really powerful language, has a really primitive build system. Developers have to wade through a complex soup of Makefiles/CMake/Gyp/ninja etc just to get a project set up. There's conan for package management, but it pales when compared to Cargo or Gradle. Moreover setting up Conan is a full time job in itself, and it's not without weird quirks either. I've not tried Bazel yet, and would love to hear if it's as good as Xooglers say.
C++ on Jupyter looks amazing, and I really hope it makes starting with C++ easier.
- coherentpony 9y ago> Developers have to wade through a complex soup of Makefiles/CMake/Gyp/ninja etc But you do this precisely once.
- mschuetz 9y agoOnce every week.
- coherentpony 9y agoI don't see how that's possible unless you're just starting out. Do you start a new project every week?
- Matthias247 9y agoI guess it also applies when you want to integrate a new third party library once a week, in cases where the libraries build system doesn't match yours.
- mschuetz 9y ago- I have to start seperate small test and prototype projects every now and then. - I have to include third party libraries occasionally, and sometimes weight if it wouldn't be just easier, faster and better for my mental health to reinvent the wheel instead. - I have to check out, test or use third party projects every now and then. They all use different build systems, different ways to use different build systems and different work around to get around limitations of build systems. I like C++11 and love C++17 but absolutely hate building and managing C++ projects. It's a mess.
- thenewwazoo 9y agoI'm a bit surprised to read this. It's been a long time since I've done C++ outside of the embedded space, but isn't this a problem that's solved by libraries and LTO? Compiling individual source units isn't terribly difficult either. There's a single tool that turns source files into object files, and a single tool to link them all up. It all feels very UNIX-y to me.
- weberc2 9y agoLTO is unrelated. Compiling individual units is only one of many build system responsibilities. There's also dependency management, cross-platform support, iterative builds, etc. And it all needs to be fast.
- harry8 9y agoCake https://github.com/dcasnowdon/Cake https://github.com/dcasnowdon/Cake Written by Matt Hermann who I believe is now at google - I've never met him. I worked somewhere that used it and have used it ever since for every greenfields C++ project I've done and just don't think about my build system anymore. For me this just works for everything I need, adding a linkflag for this .cpp file only? Dead simple, hard to imagine it being simpler. Build tests and run with valgrind equally so. I have a single top level makefile that literally just specifies targets, eg release, test, asan_test, clang_release etc. Each is a single cake line. I highly recommend it for C++ on linux (haven't used it elsewhere to say), for me it's a thing of beauty and a joy forever. Not dealing with autotools or scons or complicated make based build systems makes C++ so much nicer to work with.
- malkia 9y agoBazel is what I really like (xoogler here, used it mainly with java+protos, minor python/c++, testing, other things). Similarly - gn (though different internals, easier platform switch, etc.), buck, pants, etc. In all of these I like the single "BUILD" file per directory, and simple text file explaining dependencies. Also these tools work awesome when you are in a company, and you have underneath - dozen or more libs, sdks, projects that need to run together.
- Matthias247 9y ago> Also these tools work awesome when you are in a company, and you have underneath - dozen or more libs, sdks, projects that need to run together. I'm pretty sure it works great then. But for the bigger C/C++ ecosystem the problem is that everyone uses another build system. From Makefiles to Automake, Cmake, Gyp, Scons, Bazel, etc. everything is included. As soon as you try to use dependencies that favor a different format you either have to rewrite their project definition in your format or at least build it as an external subproject and manually add the include directories. Imho that's one of the biggest weaknesses of C++ that even outweighs language concern for me: It's often lots of work to integrate 3rd party libraries. And because of this there isn't a really great ecosystem of libraries (e.g. compared to Javascript and Java).
- pjmlp 9y agoThere is another big reason why there isn't a great ecosystem. The C mentality of some devs dragged into C++ world. Already in the 90's we had very nice high level C++ libraries, that could compete with what Java offered later. Turbo Vision on MS-DOS, Object Windows Library and Visual Components Library on Windows. All from Borland. PowerPlant on Mac OS, from Metrowerks. From Microsoft, we had MFC, which started high level like those ones (originally named Afx), but then the beta testers requested for it to just be a thin layer over Win16 and it was reborn as MFC. Many of the modern C++ patterns were already possible with those libraries, but the C wisdom made many not use them. Another modern example is Android NDK, Google writes the code in nice C++ classes, that get exposed as low level C APIs, or have a Java JNI barrier (e.g. Skia).
- curiousgal 9y ago>Gradle Ugh
- superbatfish 9y agoThe conda package manager and it's subproject conda-build are fantastic tools to solve this problem. I write scientific software (primarily a mix of C++ and Python), and I use conda for literally every dependency I need, including pure C or C++ dependencies. Most of them are already available via the conda-forge project, and the ones that aren't are easily integrated by writing my own recipes to package with conda-build.
- dimatura 9y agoI write in a mix of python and C++ as well. As such, I've also gradually moved towards using conda. What's your dev workflow for the code that's not a dependency like? Specially if the code you're developing is C++. Do you make a conda package of it as you're developing? I've found that too much of a hassle to rebuild. I usually just use CMake with the conda environment dir as the CMAKE_INSTALL_PREFIX.
- superbatfish 9y agoYeah, that's what I do also. conda-build makes it easier to use your code downstream, but doesn't obviate the need for build scripts in general. However, if you're using conda, you might be able to at least simplify your build scripts, even though you can't eliminate them. If you are okay with requiring your users to have conda, then you can exploit that fact to simplify your CMakeLists.txt in some ways. For instance, find_library, etc.. can be replaced with hard-coded links to ${CONDA_PREFIX}/lib/... (I'm not saying that's necessarily "best practice" for all projects, but it's a nice option to consider, especially in the early phases of development.)
- dimatura 9y agoAh, that's an interesting shortcut.
- ryanpepper 9y agoI've found generally it's fine for most things but issues come from when the scientific libraries are built with/without certain options. The lack of OpenMP for FFTW is annoying, for example.
- boris 9y agoCheck build2, it has a sane build model and syntax and comes with integrated package manager/repository, similat to Cargo: https://build2.org https://build2.org
- rtpg 9y agoYeah I'm a bit sad about build systems. I wanted to write a Postgres extension/fork, and was thinking "oh I'll just replace some bits with Rust". Unfortunately everything is `make`, which is great when you're setting something up and have a huge process... but it's very hard to make some changes without figuring out the entire flow. Someone that could somehow wrap make to make it easier to make incremental changes on existing projects could help fuel a lot more experimental changes.
- boris 9y ago>... wrap make to make it easier to make ... I think there is a deep truth in (unintended?) pun: those who don't understand make are bound to reinvent it, poorly.
- rtpg 9y agoI feel like I "get" make, but when you have autotools in front of it you end up with stuff like [0], and Makefiles kicking off other Makefiles. It's not the worst thing to ever grace the planet by a long shot, but I think it suffers from the same problem that bash scripts have. Everything is string-ly typed and you can only build up a thing to a certain level of complexity easily. There's of course a lot of requirements in systems software, of course. And a lot of difficulty stems more from the C ecosystem's difficulties with packaging (where are the C equivalents to "environments" you find in Python/Ruby so you don't have to pass every lib in explicitly?) I think there's some useful opportunities somewhere here. [0]: https://github.com/postgres/postgres/blob/master/src/Makefile.global.in https://github.com/postgres/postgres/blob/master/src/Makefil...
- boris 9y ago> Everything is string-ly typed and you can only build up a thing to a certain level of complexity easily. Yes, make was designed for the 1970 world, where all you care about is building simple utilities on Unix. There was no today's complexity (out of tree builds, cross-compilation, etc) nor "alien" platforms like Windows where people have spaces in their paths. What we need is to redesign make to handle today's requierements. And this is what we are trying to do with build2.
- keerthiko 9y agoC++ was the first programming language I picked up that made me feel like I was really making something (after VisualBASIC and HTML), when I was 13. Things were simpler back then. I used Borland C++ and it could produce .exe exports from .cpp sources, pulling in referenced #includes. Running it in Windows would launch a little DOS prompt that ran your program and then quit (unless you put a getch()!) Like any teenager tinkering, I opened up some sample cpp file that came with the compiler and started just throwing in cout<< all over the place doing random stuff with variables. My older brother explained "loops", "functions" and later the basics of "arrays" and I completed my first game by 16, written purely in C++ -- a Tank clone that was a single long-ass cpp file using purely #include<graphics.h> calls, putting individual pixels on a 640x480 screen. I hadn't learned what classes were yet, so it was some form of "functional programming", just starting from a void main() The point was, it was easy to tinker and learn and make stuff and explore in C++, the language isn't innately arcane. I didn't even have the internet back then to look stuff up. A teacher gave me a textbook for "graphics in C++" because my high school (which I wasn't in yet) computer science curriculum didn't cover graphics, but I hated copying code from the textbook (it seemed outdated) so I just opened up header files and tried to call functions I saw in there. I didn't need to use any fancy C++ syntax, just the basics my brother taught me. No make files, no build scripts, no gcc. Just an IDE that existed on a floppy disk and the most common OS available at the time (DOS). It must be a sign I'm getting crotchety and old, but "back in my day" C++ wasn't such a confounding beast. And I'm sad to say I think modern-day python is going down a similar path, it started out intending to be the easiest language to tinker in, but it's slowly becoming arcane just to import a module and launch a program for a beginner. I stepped back into C++ recently trying to make something "I can see" at from scratch, and it's damn nigh impossible without visiting 4-8 different instructional sites depending on how you define "something I can look at".
- pjmlp 9y agoPicking up your example, that is exactly why ANSI C++ people want to have some kind of basic 2D support on the standard. Yet the naysayers state that apparently we can have standard IO, filesystem and networking support, but not 2D. The reason being that not all scenarios have graphical displays, as if all deployment scenarios always have filesystem and networking stacks.