6 ms·
I may be wrong, but I was under the impression that this was portable on all POSIX systems: uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
by avar 8y ago
I may be wrong, but I was under the impression that this was portable on all POSIX systems:
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
ifeq ($(uname_S),Linux)
HAVE_LINUX_SPECIFIC_STUFF = Yes
endif
This is how git does its conditional compilation purely powered by Makefile logic: https://github.com/git/git/blob/master/config.mak.uname https://github.com/git/git/blob/master/config.mak.uname
- LukeShu 8y agoThat requires GNU Make; neither $(shell) nor ifeq are in POSIX Make.
- jwilk 8y ago":=" assignments are not in POSIX either.
- jstanley 8y agoMakefile logic is basically just an ifdef one level up.
- chris_wot 8y agoSo what do you do then?
- convolvatron 8y agoany place you have to parameterize signatures or behaviors or types, calling it something meaningful and define it in a platform/compiler/os specific header. sure, in the end its the the same thing, but i find it to be easier to manage over time. and when you need to port to a new platform/compiler/os, you have a list of the important dependencies at hand...maybe you have to define a new one
- jstanley 8y agoI don't consider ifdefs harmful. But if you do, you must surely consider logic in Makefiles equally harmful.
- chris_wot 8y agoWhy so?
- monocasa 8y agoBut your per platform build logic pretty much has to exist anyway on any non-trivial project, as differences in compilers (even different versions of the same compiler) crop up. Better to just stick that distinction all in one place, IMO.
- MaulingMonkey 8y agoWhich is exactly why I'll often try and keep build configuration in C++ #ifdef s. Everyone wants/needs proper Visual Studio projects in gamedev. And XCode projects. Maybe makefiles on top of that for some of your other platforms. Maybe a project generator to generate it all. Maybe some .props files to express things that the project generator can't. And then CI build server configuration on top of that. And then, because you're trying to another CI solution, a second CI build configuration. It's a mess of multiple unrelated tools - so it will never be in "one place" at the build system level. Shoving it in there anyways causes tons of duplicate build configuration logic. Alternatively, I could minimize the configuration in there - to just the bare minimum needed to drive high level configuration - and then centralize all the derived configuration in the one thing that's shared between them all: C++. C++ is a common denominator among my coworkers. When they have to dig through Gradle or Ant configuration because we're doing Android builds, I become a bottleneck. Lame. Yet another project generator? Ends up on my plate again. Lame. My coworkers have legitimately better things to be doing than becoming build system experts. They already understand "hey, I can pull configuration #define s into a separate file and only rebuild the things that #include it", meaning minor settings tweaks don't invalidate several build hours worth of compiled translation units, something I still don't know how to effectively do in some build systems.
- monocasa 8y agoI mean, that's the whole point of cmake, ninja, etc. They'll build all of those projects, complete with testing and other ancillary projects. You don't have to be an "build system expert". And you can absolutely make your build times better than what you're citing, coming from someone with binaries measured in tens of megs with templates out the wazoo. Just break up your dependencies. Seriously, you can almost certainly get ten to hundred times faster with only a little bit of work (which more than pays for itself in increased productivity).
- jwilk 8y ago> $(shell sh -c 'uname -s 2>/dev/null || echo not') Is there a reason they don't use simpler: $(shell uname -s 2>/dev/null || echo not) ?
- JdeBP 8y ago* https://git.kernel.org/pub/scm/git/git.git/commit/Makefile?id=f7c153431b4049e7697664dee4a3d71013422f9d https://git.kernel.org/pub/scm/git/git.git/commit/Makefile?i...
- comex 8y agoAck… please don’t do this. It will break if you’re cross-compiling binaries for a different OS than the OS you’re building on. If you want to do per-OS configuration in a Makefile or some type of configure step, that’s fine – but you should do it either based on a target triple (--host in autoconf-speak) which can be overridden by the user, or by running the given compiler on test programs and checking the output (like autoconf does, but ideally with one or two tests rather than a bazillion of them).
- Annatar 8y agoNo; this is GNUmake specific syntax. The simplest and cleanest thing to do is to write a Makefile per uname(1).compiler, like so: Makefile.Linux.SunStudio Makefile.Linux.icc Makefile.Linux.PGI Makefile.Linux.GCC Makefile.AmigaOS.vbcc Makefile.AmigaOS.DiceC Makefile.AtariTOS.gcc Makefile.Spearmint.gcc Makefile.illumos.gcc Makefile.illumos.SunStudio ...and so on. The source code and generic targets like clean: would go into a central Makefile.core which would then be included by the OS.compiler specific Makefile. The OS specific Makefile would only set $CC, $CXX, $FC, $CFLAGS, $CXXFLAGS, $FFLAGS and so on. This way, no configure system would be needed and adding support for a new $OS.compiler suite would be trivial. The code would have to be so clean as to allow compilation by any compiler of course.