lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Fri, Mar 08, 2013 at 11:49:42AM +0000, David Given wrote:
> Enrico Tassi wrote:
> > On Fri, Mar 08, 2013 at 01:08:52AM -0700, Spencer Parkin wrote:
> >> define BUILD_OBJ_RULE =
> >> $(1): $(2)
> >>     $$(CPP) $$(FLAGS) -c $$< -o $$@
> >> endef
> >> $(foreach src, $(SRCS), $(eval $(call BUILD_OBJ_RULE, $(patsubst %.cpp,
> >> $(BUILD)/%.o, $(notdir $(src))), $(src))))
> > 
> > Nobody would write a Makefile like this one.
<snip>
> 
> GNU make does provide some built-in features to make this sort of thing
> a little less painful, such as target-specific variables, but they've
> got weird edge conditions that make them less useful than you might think.
> 
> The absence of any kind of code abstraction is one of the reasons why
> makefiles tend to balloon into unmaintainable tangles. The best example
> of a modular Make build system I've seen is the one used by the Android
> platform build system and NDK. It uses include files rather than macros,
> and a user-specific file looks like this:

Make is quite abstract, people just don't learn the abstractions because
they usually just focus on getting some piece of code to compile so they can
move on. It's like approaching a programming language as "that thing which
lets me print 'hello world'" and then complaining about how poorly it
abstracts the printing of 'hello world'.

I've yet to meet a build system that is as elegant, flexible, and simple as
make. Granted, you need modern GNU or BSD make implementations for dynamic
rule generation, and the various choices they make are debatable. I prefer
the BSD style for conditionals, but the GNU-style macro extensions are more
in harmony with the [nascent] list semantics of traditional make.

> include $(CLEAR_VARS)
> LOCAL_MODULE := modulename
> LOCAL_SRC_FILES := list of source files
> ...other LOCAL_ variable definitions...
> include $(BUILD_<type of thing you want to build>)
> 
> This is slightly friendlier than the macro-based alternative above, but
> is still nigh incomprehensible.

The problem here is that concepts like "module" or "library" aren't
universal. All the make alternatives apply perfectly reasonable assumptions
for the domain in which their authors hack, but those assumptions quickly
fall to pieces elsewhere. Make existed before dynamically linked libraries
existed, and it'll exist when those ago away (e.g. when libraries can be
fetched automatically over the internet). That's why make excels at cases
where you're doing non-vanilla compilations and source management.

The syntax is a stumbling block, admittedly. But so is any language which
isn't derivative of C or Pascal. Make is a declarative language, like SQL or
XSL. You don't program in SQL or XSL as-if you're programming in an
imperative language. Likewise with make.

I think it's telling that most make "alternatives" expose a primarily
imperative language model. That, more than anything else, is what makes them
attractive, I think. And that's a shame, because that language model doesn't
suit the task very well.