Best practices in regard to -D_TIME_BITS=64

Kaz Kylheku kaz@kylheku.com
Wed Jan 5 20:12:39 GMT 2022


On 2022-01-04 20:43, Paul Eggert wrote:
> On 1/4/22 16:53, Sam James wrote:
> 
>> FWIW, we've hit issues in Gentoo with wget/gnutls: 
>> https://bugs.gentoo.org/828001 <https://bugs.gentoo.org/828001>.
> 
> Thanks for the heads-up.
> 
> Yes, not surprised about that, as mixing 64-bit time_t apps with
> 32-bit time_t libraries is a recipe for trouble if the APIs depend on
> time_t. For apps that use such libraries, it really has to be a big
> bang: configure all that stuff with --disable-year2038 -D_TIME_BITS=32
> before, and with --enable-year2038 CFLAGS=-D_TIME_BITS=64 after.
> 
>> https://wiki.gentoo.org/wiki/Project:Toolchain/time64_migration

I looked at this Wiki page and one thing stands out.

I would recommend to the Gentoo people to forget about CPPFLAGS, and
just use CFLAGS, even for -D material. If you put -D_TIME_BITS=64
into CFLAGS, you then don't have to deal with packages that perfectly
well honor CFLAGS, but not CPPFLAGS.

People don't know about CPPFLAGS. It seems to be just something invented
by GNU Make, referenced in some of its built-in recipes. Getting all
upstream packages to recognize CPPFLAGS (or else patching them locally)
is just a lot of make-work (pun intended).

I'm also aware of a historic *ad hoc* practice of using CPPFLAGS for C++ 
CFLAGS;
i.e. that for which CXXFLAGS is a better practice.

For what it's worth, POSIX's description of make mentions no CPPFLAGS,
but does mention CFLAGS, LDFLAGS. (It also doesn't mention LDLIBS, 
another
separation variable, but that I suspect is much more entrenched than 
CPPFLAGS,
and the separation is quite essential: you need to do that any time you 
specify
additional -l arguments for linking.)

GNU's built-in rules do some nonsensical things like:

   LINK.c := $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

(If CPPFLAGS is needed all the way through linking C, what purpose does 
it serve
separate from CFLAGS? And if I'm writing my own linking recipe, do I 
have to
reproduce this?)

CPPFLAGS is something that would be useful for calling a standalone C 
preprocessor
that doesn't understand compiler options.

But:

You don't need that in a GCC environment, because you can call gcc with 
options
that perform preprocessing only, and still pass other options specific 
to
compiling.

Not only that, but GNU cpp is tolerant to gcc options not pertaining to
preprocessing:

No problem:

$ echo | cpp -fstrict-aliasing > /dev/null

$ echo | cpp -fNoNExistent > /dev/null
cpp: error: unrecognized command line option ‘-fNoNExistent’; did you 
mean ‘-fno-ident’?

You don't need CPPFLAGS in a non-GCC environment with GNU make, because 
you
can easily do some GNU Make text processing to separate the preprocessor
options, if you need them.

Proof-of-concept demo:

$ make CFLAGS="-Wall -I/path/to/include -UMAC -DFOO=bar -o foo.o -lm"
cpp_only_flags == -I/path/to/include -UMAC -DFOO=bar

Source:

cpp_only_flags := $(foreach arg,                        \
                      $(CFLAGS),				\
                      $(or $(filter -D%,$(arg)),         \
		          $(filter -U%,$(arg)),         \
		          $(filter -I%,$(arg)),         \
		          $(filter -iquote%,$(arg)),    \
			  $(filter -W%,$(arg)),         \
			  $(filter -M%,$(arg))))        \
                   $(CPPFLAGS) # also pull this in

all:
	@echo cpp_only_flags == $(cpp_only_flags)

In an application, if you want separated C preprocessing flags, that
is what you have to do; you can't assume that you're built in
a distro environment which will hand them to you in a separate
CPPFLAGS variable.


More information about the Libc-alpha mailing list