News for hackers. Stuff that matters.
Re:How to Write Portable C Without Complicating Your Build by zbuf on Friday March 31, 2017 @04:53AM (#14002089)
> If you write your own configure, people may expect to be able to [...] It's a tedious task and easy to get wrong.

The author's point is to do <em>without</em> a configure step entirely, not write your own.

A standard Makefile is perfectly capable of implementing these things in a manner which is clean, reasonably portable and without the level of indirection that makes things hard to debug.

My own experience is that autotools has evolved to feel less standard than the modern platforms it purports to smooth over the differences in; I seem to frequently find that I can't generate a 'configure' for a 3rd party software or libraries from Git repositories because I of the wrong autotools versions. Efforts to investigate this by unpicking the various macros etc. provided in the build have almost always been unsuccessful, leaving me building from distributed .tar.gz files. With something that feels like such a moving target after 30 years, I'm glad to see people realising the benefit of a simple Makefile that's easy to customise for the edge cases.

Re:How to Write Portable C Without Complicating Your Build by zuzun on Friday March 31, 2017 @07:02AM (#14002609)
There's no way you can do what autotools does in a Makefile without implementing half of autotools yourself. How do you check for headers? How do you check for functions? How do you test if qsort_r expects

    (*)(void*, const void*, const void*) 
or

    (*)(const void*, const void*, void*)
as function pointer? If people are forced to detect that kind of stuff in Makefiles, they get the urge to match `uname` against some hard-coded platforms and that's a terrible solution.
Re:How to Write Portable C Without Complicating Your Build by coldtea on Friday March 31, 2017 @07:58AM (#14002859)
>There's no way you can do what autotools does in a Makefile without implementing half of autotools yourself.

That's part of the argument: with standards compliant code, you don't need to do "what autotools does".

Re:How to Write Portable C Without Complicating Your Build by zuzun on Friday March 31, 2017 @11:30AM (#14004780)
ENOTSUP is part of the standard and I do have autotools macros checking if some function calls produce that error value on the host system.
Re:How to Write Portable C Without Complicating Your Build by zbuf on Friday March 31, 2017 @08:13AM (#14002922)
> no way you can do what autotools does in a Makefile

Well, you're responding to something that wasn't actually said; "these things" quotes specifically the list of requirements given by the previous poster -- CFLAGS etc.

Your example is indeed valid, it's an ugly case and I agree that testing for the feature specifically (rather than arch, compiler) is always preferred. But let's look at the practicalities -- how many of these cases do I actually need in a codebase to tip the balance that would justify use of autoconf? In your example, a simple #ifdef against the platform (Windows/BSD/Linux) and it's gone. qsort_r is off limits for massively portable program anyway, so autoconf's ability to help is limited anyway.

Re:How to Write Portable C Without Complicating Your Build by marcosdumay on Friday March 31, 2017 @01:05PM (#14005770)
> a simple #ifdef against the platform (Windows/BSD/Linux) and it's gone.

That's equivalent to the uname trick the GP was complaining about. That means your software won't compile in a lot of platforms.

On a small scale, I don't think that's a big problem. Somebody on those platforms only has to add the correct conditions to your #ifdef forest and if he sends the update back, other people on the same platform won't even have the same problem. It's not much different from software not working on untested platforms.

It starts becoming a problem when done often, or on high level (at the calling stack) code.

Re:How to Write Portable C Without Complicating Your Build by zbuf on Friday March 31, 2017 @04:39PM (#14007962)
> That means your software won't compile in a lot of platforms.

Is won't anyway; qsort_r has already limited me to a tiny number of platforms. If I care about further portability, autotools can't do anything to help me; my next step is not autotools, it's "don't use qsort_r"

Re:How to Write Portable C Without Complicating Your Build by maxlybbert on Friday March 31, 2017 @09:32AM (#14003540)
> How do you test if qsort_r expects

    > (*)(void*, const void*, const void*) 
> or

    > (*)(const void*, const void*, void*)
You can write C++ code that uses templates and SFINAE to do it. I have. I will admit, it looks like garbage. But it is possible.
Re:How to Write Portable C Without Complicating Your Build by jandrese on Friday March 31, 2017 @12:13PM (#14005227)
Who uses the latter form? I don't think I've ever seen that before.

Also, isn't the first supposed to be:

  void*, size_t, size_t, int (*cmp)(const void*, const void*)
Or are you using some wtf version that hides the element size and count behind a void*?
Re:How to Write Portable C Without Complicating Your Build by maxlybbert on Friday March 31, 2017 @12:51PM (#14005634)
The signatures came from another answer. I have no idea what the signatures are, or should be, or why there's a difference.

My SFINAE code was to handle a similar problem picking between a GNU-specific strerror_r and a POSIX strerror_r that have different signatures (both are available on Linux, determined by whether certain macros are set: https://linux.die.net/man/3/strerror_r , I couldn't just rely on those macros because I wanted my code to compile on any POSIX platform).

Re:How to Write Portable C Without Complicating Your Build by zbuf on Friday March 31, 2017 @02:19PM (#14006483)
You're commenting on the prototype for qsort() itself, whereas the original point was about the function pointer that is an argument to qsort_r().

Both Linux and BSD chose to add a non-standard qsort_r(), each choosing different ways to do it.

Re:How to Write Portable C Without Complicating Your Build by tannhaeuser on Friday March 31, 2017 @06:58AM (#14002589)
I wish standard (POSIX) Make would be sufficient but it frequently isn't. While some Make features from GNU and BSD Make made it into the POSIX spec (such as "include"), I frequently find myself desiring a more orthogonal facility to integrate output of external programs into Make builds. That is, by using POSIX Make's "VAR=`cmd`" syntax with backtick-quoted commands (or other shell evaluation syntax), you can define macros programmatically for incorporation into build rules as lazily evaluated text substitution variables, but you can use those only in build rules rather than in requisites or targets (where they get interpreted verbatim). A partial solution would be adopting GNU Make's eager evaluation syntax (VAR:=`...`) into POSIX.

OTOH, while I'm not a big fan of autotools internals (especially libtool), being able to run "./configure && make install" on tens of thousands of F/OSS packages is something I'd hate to loose. In fact, the extreme consistency in installation procedures (including use of pkg_conf etc.) and discipline in directory layout accross so many F/OSS packages is something I very much admire, given it's an unexpected outcome of a "Bazaar" style development model.

Re:How to Write Portable C Without Complicating Your Build by dTal on Friday March 31, 2017 @12:11PM (#14005197)
>"./configure && make install"

You forgot 'make'!

I'm tempted to turn this into a cheap shot about how the consistency obviously isn't worth much, but I won't.

Re:How to Write Portable C Without Complicating Your Build by dfox on Friday March 31, 2017 @01:05PM (#14005775)
Explicitly doing 'make' is redundant for makefiles generated by any version of automake I've ever used. Dependencies are setup correctly so that install also builds everything that it installs and isn't already uptodate (I'm not sure whether 'install' also explicitly depends on 'all')
Re:How to Write Portable C Without Complicating Your Build by derefr on Friday March 31, 2017 @03:07PM (#14007089)
The usual reason to separate them is that if you're installing to a prefix that needs root privileges to write to, then you'll be doing something like:

    ./configure && make && sudo make install
If you do this instead:

    ./configure && sudo make install
...then the compiler toolchain gets invoked as root and all the intermediate build products end up owned by root.
Re:How to Write Portable C Without Complicating Your Build by xtreme on Saturday April 01, 2017 @02:29AM (#14010841)
There is another reason. `make -j4 && make install' would be faster than just `make install' (multi-process vs. single-process).
Re:How to Write Portable C Without Complicating Your Build by atso on Saturday April 01, 2017 @07:05AM (#14011550)
You can do `make -j4 install`. Works as intended.
Re:How to Write Portable C Without Complicating Your Build by vbernat on Friday March 31, 2017 @06:07AM (#14002405)
He also says later in the post you can write your own configure with a bit of bourne shell. If you expect your software to be widely distributed, a custom build script is a pain for distributions as most of them are heavily relying on ./configure && make with the appropriate arguments. Distributions also rely on the ability to override certain flags, something easy to do with autotools and quite hard with plain Makefiles (compare ./configure CFLAGS=... and make CFLAGS=..., the former don't override upstream CFLAGS).

I don't object that many projects have convulated and dated autotools scripts notably because they don't age well. It's easy to accumulate a lot of crap.

Most projects don't get autotools because they don't know how to use plain Makefile. They do because autotools bring much more than that.