Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Best way to portably implement "make install"

45 views
Skip to first unread message

Frederick Gotham

unread,
Jan 14, 2020, 8:38:39 AM1/14/20
to

NOTE: Usenet has been around since 1979/1980. In these past 40 years, people have taken likings and dislikings to cross-posting and multi-posting. Irrespective of my own preference, it is clear to me from being on Usenet since about 2002 that far more people dislike cross-posting. I have therefore multi-posted to two groups, a C one, and a C++ one.

A few months ago I posted about my generic Makefile that builds a C/C++ program from all the source files in the current directory. I've been using this Makefile for the past few months on loads of different programs (big and small) and it works well.

Moving on. . .

What would be the best way to implement "make install" as portably and generically as possible? Here's what I've got so far:

#If DESTDIR is not set then set it
ifeq ($(DESTDIR),)
DESTDIR = /usr/bin
endif

.PHONY: install
install: $(PROGRAM)
cp $< $(DESTDIR)

.PHONY: uninstall
uninstall:
$(RM) $(DESTDIR)/$(PROGRAM)


I have seen some people use the environment variable "PREFIX" in their makefiles but I'm not sure if it would do here. Should I even bother trying to implement this for Microsoft? For example I could copy the file to "c:\Program Files".


Oh by the way here's the entire Makefile. It's written to be as flexible as possible (for example if the user does make SOME_VARIABLE=some_value):

PROGRAM = prog

INC_DIRS += -I./

CFLAGS_CXXFLAGS_IN_COMMON += -pedantic -Wall -Wextra -rdynamic -funwind-tables -fno-omit-frame-pointer -fdump-rtl-expand -fno-common
CFLAGS += $(INC_DIRS) $(CFLAGS_CXXFLAGS_IN_COMMON) -std=c99
CXXFLAGS += $(INC_DIRS) $(CFLAGS_CXXFLAGS_IN_COMMON) -std=c++11

LDFLAGS += $(CFLAGS_CXXFLAGS_IN_COMMON)
LDLIBS +=

SRC_FILES_C := $(wildcard *.c)
SRC_FILES_CXX := $(wildcard *.cpp)

#If there's no C++ files then use the C compiler to link
ifeq ($(SRC_FILES_CXX),)
LINKER = $(CC)
else
LINKER = $(CXX)
endif

OBJECTS += $(SRC_FILES_C:.c=.c.o) $(SRC_FILES_CXX:.cpp=.cpp.o)

DEPENDENCIES += $(OBJECTS:.o=.d)

.PHONY: all
all: $(PROGRAM) $(DEPENDENCIES)

#This rule runs the linker to combine object files into one executable binary file
$(PROGRAM): $(OBJECTS)
$(LINKER) $(LDFLAGS) $^ $(LDLIBS) -o $@

#This rule makes dependencies files for the source files
.PRECIOUS: %.c.d
%.c.d: %.c
$(CC) $(INC_DIRS) -MM -MT $(<:.c=.c.o) $< -MF $@

.PRECIOUS: %.cpp.d
%.cpp.d: %.cpp
$(CXX) $(INC_DIRS) -MM -MT $(<:.cpp=.cpp.o) $< -MF $@

#This rule compiles the source files to object files
%.c.o: %.c %.c.d
$(CC) $(CFLAGS) -o $@ -c $<

%.cpp.o: %.cpp %.cpp.d
$(CXX) $(CXXFLAGS) -o $@ -c $<

#This next line pulls in all the dependency files (if they exist, and it's not "make clean")
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPENDENCIES)
endif

.PHONY: clean
clean:
$(RM) $(DEPENDENCIES) $(OBJECTS) $(PROGRAM) $(OBJECTS:.o=*.expand)

#These next two rules to (un)install are only for Linux

#If DESTDIR is not set then set it
ifeq ($(DESTDIR),)
DESTDIR = /usr/bin
endif

.PHONY: install
install: $(PROGRAM)
cp $< $(DESTDIR)

.PHONY: uninstall
uninstall:
$(RM) $(DESTDIR)/$(PROGRAM)

Marcel Mueller

unread,
Jan 14, 2020, 1:22:57 PM1/14/20
to
Am 14.01.20 um 14:38 schrieb Frederick Gotham:
> A few months ago I posted about my generic Makefile that builds a C/C++ program from all the source files in the current directory. I've been using this Makefile for the past few months on loads of different programs (big and small) and it works well.

You probably should not reinvent the wheel.
There are several build utilities around. There is no need for another
one that works sometimes. If you want to be portable you cannot rely on
gcc neither on Gnu make. Other compilers and tool chains are common too.

For C/C++ cmake is a reasonable starting point. Although like any other
tool it has some drawbacks, but it supports plenty much of platforms and
tool sets, including make install.


Marcel

Mr Flibble

unread,
Jan 14, 2020, 2:36:05 PM1/14/20
to
bleh.

CMake.

/Flibble

--
"Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin

“You won’t burn in hell. But be nice anyway.” – Ricky Gervais

“I see Atheists are fighting and killing each other again, over who doesn’t believe in any God the most. Oh, no..wait.. that never happens.” – Ricky Gervais

"Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Byrne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say."

Paavo Helde

unread,
Jan 14, 2020, 3:47:15 PM1/14/20
to
I agree with other responders. The above looks more like assembler or
PostScript code, i.e. not really something meant for humans to write.
And the result looks pretty non-portable and limited to a single type of
projects.

While I have done my share of makefile programming in the past I'm ready
to admit I never got it quite right; by looking at makefiles generated
by CMake I can now understand why.

So what's wrong with using CMake instead?

Siri Cruise

unread,
Jan 14, 2020, 4:39:04 PM1/14/20
to
In article
<878b2dc4-fbfe-4f1d...@googlegroups.com>,
Frederick Gotham <cauldwel...@gmail.com> wrote:

> What would be the best way to implement "make install" as portably and
> generically as possible? Here's what I've got so far:

Don't use make. Use a bourne shar. Deal with parameters,
interrogate the environment, etc and write out the payload and
the makefile where convenient. Then do the make.

Keep the script readable and as short as possible. Keep the
makefile readable.

--
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @
'I desire mercy, not sacrifice.' /|\
The first law of discordiamism: The more energy This post / \
to make order is nore energy made into entropy. insults Islam. Mohammed

Siri Cruise

unread,
Jan 14, 2020, 4:39:38 PM1/14/20
to
In article <qvl9c9$148$1...@dont-email.me>,
Paavo Helde <myfir...@osa.pri.ee> wrote:

> So what's wrong with using CMake instead?

What's not?

Jorgen Grahn

unread,
Jan 14, 2020, 5:07:25 PM1/14/20
to
On Tue, 2020-01-14, Paavo Helde wrote:
> On 14.01.2020 15:38, Frederick Gotham wrote:

>> A few months ago I posted about my generic Makefile that builds a
>> C/C++ program from all the source files in the current
>> directory. I've been using this Makefile for the past few months on
>> loads of different programs (big and small) and it works well.

...
>> OBJECTS += $(SRC_FILES_C:.c=.c.o) $(SRC_FILES_CXX:.cpp=.cpp.o)
>>
>> DEPENDENCIES += $(OBJECTS:.o=.d)
>>
>> .PHONY: all
>> all: $(PROGRAM) $(DEPENDENCIES)
...

> I agree with other responders. The above looks more like assembler or
> PostScript code, i.e. not really something meant for humans to write.
> And the result looks pretty non-portable and limited to a single type of
> projects.

I believe that was his goal: a single Makefile for all matching
projects, not meant to be easily read and understood.

Like I argued the first time around, a hand-written Makefile,
written /for a certain project/, can be written clearly and elegantly
(modulo a dozen lines of boilerplate for the dependency generation).

IMO, this one of mine is an example: <git://snipabacken.se/groblad>.

But the OP wanted (as I understood it last time) a Makefile he could
copy into any directory containing source code, so he could ignore
whatever build system was already in place.

> While I have done my share of makefile programming in the past I'm ready
> to admit I never got it quite right; by looking at makefiles generated
> by CMake I can now understand why.

It's autogenerated makefiles, designed to use recursive make strategy;
they are bound to be atypical.

> So what's wrong with using CMake instead?

Personally I've never been able to understand CMake. Trivial tasks are
easy; other tasks end up, IME, an exercise in cargo-culting and
trial-and-error.

For the OP's use case, CMake could be a better fit.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
0 new messages