2
votes

When setting package/lib _SOURCES or per-package/lib flags (CFLAGS, LDFLAGS, LDADD, etc.) conditionally, is it better to conditionally append to the package's flags, e.g.:

bin_PPROGRAMS = mypkg
mypkg_SOURCES = mypkg.c
if OS1
mypkg_SOURCES += os1.c
else
if OS2
mypkg_SOURCES += os2.c
endif
endif

or to conditionally assign variables and concatenate them all into the package's flags (whether populated or null), e.g.:

if OS1
os1_src = os1.c
else
if OS2
os2_src = os2.c
endif
endif

bin_PROGRAMS = mypkg
mypkg_SOURCES = mypkg.c $(os1_src) $(os2_src)

I've seen it both ways and I can see advantages to each. With the former, the actual final action of adding those flags to the package are clear in the conditional, and you haven't crowded the line with variables that don't actually mean anything in a given build. In the latter, what's actually included in the package is consolidated on one line and you don't have unseen appendment happening somewhere else, but you might not really know what's going on in that opaque variable name.

I guess another option is to do something like option 2, but assign the variables with the configure script (configure.ac with AC_SUBST). But I've been keeping my configure scripts purely detecting features available, and choosing which to use in Makefiles.

Does one of them have a technical downside or nasty side-effect?

2

2 Answers

2
votes

The differences you observe are largely a matter of style, which is subjective and thus largely off-topic here. But your actual question is pretty objective:

Does one of them have a technical downside or nasty side-effect?

No, none of which I am aware. Either approach will work fine, at least in isolation. A larger context might provides reasons to prefer variations on the second approach, such as re-use of the variables in conjunction with more than one target. That would be more likely the case for preprocessor or link options than for choice of source files, however.


Personally, I would structure the particular case you've presented a bit differently:

if OS1
os_src = os1.c
else
if OS2
os_src = os2.c
endif
endif

bin_PROGRAMS = mypkg
mypkg_SOURCES = mypkg.c $(os_src)

To be sure, this is a matter of style, so take it for whatever it's worth to you. Here, the usage of the variable matches the structure of the condition: OS1 and OS2 are alternatives, so between them they control the value of just one variable. The meaning of that variable is therefore clearer, both at the point where its value is set and at the point it is used.

Multiple variables make more sense for multiple distinct, unrelated conditions.

1
votes

I would add some more typical patterns:

os1_src = os1.c
os2_src = os2.c
if OS1
  myos = os1
endif
if OS2
  myos = os12
endif

mypkg_SOURCES = mypkg.c $($(myos)_src)

another:

if OS1 os1 = yes os2 = no endif if OS2 os1 = no os2 = yes endif $(os1)src = os1.c $(os2)src = os2.c

mypkg_SOURCES = mypkg.c $(yessrc)

Same approach can be used to supply os- or processor- or configuratipn-specific build flags. Often, there are some common settings that are used for more than one module, while other flags are module-specific.

Each approach can be misused and lead to nasty consequences.

The main risk is that some flags or settings for one module will not get reset properly and some settings for another module will 'spill' unintentionally. But also, some module can miss some common flag.

To reduce these risk, try to stick with same technique even if your build contains many modules.