commit 2d7a57c4fd350dd707aef47f8474c83fdeefdb6d (patch)
parent 196eed4cde955aee098091b003e65ddf17e4d004
Author: Alex Karle <alex@alexkarle.com>
Date: Tue, 28 Sep 2021 01:07:39 -0400
blog: Add new entry on `make obj`; what, how, why
This is kind of an immediate followup to text-only(7),
which largely skimmed over the HOW and focused more on
just announcing text.alexkarle.com.
I'm not 100% in love with the flow/wording of this draft,
but I've read it a few times and I think it's ready to
share. I suppose I can always edit it later.
Diffstat:
M | blog.7 | | | 23 | ++++++++++++++--------- |
A | make-obj.7 | | | 156 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 170 insertions(+), 9 deletions(-)
diff --git a/blog.7 b/blog.7
@@ -18,34 +18,39 @@ Otherwise, posts below are from newest to oldest:
.Pp
.Bl -bullet -compact
.It
+.Xr make-obj 7
+\(em out-of-tree builds with BSD
+.Xr make 1
+(09/28/2021)
+.It
.Xr text-only 7
-- announcing text.alexkarle.com (09/20/2021)
+\(em announcing text.alexkarle.com (09/20/2021)
.It
.Xr creative-coding 7
-- learning through creative limitation (07/18/2021)
+\(em learning through creative limitation (07/18/2021)
.It
.Xr use-feeds 7
-- RSS/Atom feeds; what, why, and how (02/09/2021)
+\(em RSS/Atom feeds; what, why, and how (02/09/2021)
.It
.Xr my-old-man 7
-- Adventures in using
+\(em Adventures in using
.Xr mdoc 7
for this site's source (12/30/2020)
.It
.Xr on-writing 7
-- On Writing Without an Audience (10/22/2020)
+\(em On Writing Without an Audience (10/22/2020)
.It
.Xr self-hosted 7
-- Migrating to a Self-Hosted Site (07/19/2020)
+\(em Migrating to a Self-Hosted Site (07/19/2020)
.It
.Xr BLM 7
-- Black Lives Matter (07/13/2020)
+\(em Black Lives Matter (07/13/2020)
.It
.Xr domain-names 7
-- What's in a (domain) name? (03/24/2020)
+\(em What's in a (domain) name? (03/24/2020)
.It
.Xr a-new-hope 7
-- A New Hope (12/19/2019)
+\(em A New Hope (12/19/2019)
.El
.Sh SEE ALSO
.Bl -bullet -compact
diff --git a/make-obj.7 b/make-obj.7
@@ -0,0 +1,156 @@
+.Dd September 28, 2021
+.Dt MAKE-OBJ 7
+.Os
+.Sh NAME
+.Nm make-obj
+.Nd out-of-tree builds with BSD
+.Xr make 1
+.Sh DESCRIPTION
+If you've ever built parts of OpenBSD from source,
+you may know that the sequence of commands recommended by
+.Xr release 8
+is:
+.Pp
+.Bd -literal -offset indent
+$ make obj
+$ make
+# make install
+.Ed
+.Pp
+If, like me, you've forgotten the
+.Ql make obj
+step,
+you'll find yourself with many derived files in the
+current directory of whatever program you're building.
+By running
+.Ql make obj
+first,
+a directory called
+.Pa obj
+appears and the derived files
+(usually
+.Pa *.o
+files) are placed there instead.
+Cleverly, the
+.Pa obj
+directory is actually a symlink to
+another filesystem under
+.Pa /usr/obj ,
+making it truly an out-of-tree build.
+.Pp
+Up until recently,
+I understood what the
+.Ql obj
+target did and why it was useful.
+However, it wasn't until I tried to replicate it with the
+build for text.alexkarle.com
+that I discovered how it worked.
+I figured I'd document it here in case it helps anyone else.
+.Sh HOW IT WORKS
+My discovery of the inner workings of this target was a classic
+lesson in RTFM.
+After 10-15 minutes of trying to parse the makefiles in
+.Pa /usr/share/mk ,
+I finally searched for
+.Pa obj
+in the
+.Xr make 1
+man page,
+and sure enough the answer was the first hit!
+I've copied it for convenience below
+(licensed under the BSD-3 clause):
+.Pp
+.Bl -tag -offset indent
+.It Va .OBJDIR
+Path to the directory where targets are built.
+At startup,
+.Ic make
+searches for an alternate directory to place target files.
+.Ic make
+tries to
+.Xr chdir 2 into
+.Ev MAKEOBJDIR
+(or
+.Pa obj
+if
+.Ev MAKEOBJDIR
+is not defined),
+and sets
+.Va .OBJDIR
+accordingly.
+Should that fail,
+.Va .OBJDIR
+is set to
+.Va .CURDIR .
+.El
+.Pp
+With this new knowledge,
+getting an out-of-tree build was almost as simple as running
+.Ql mkdir obj
+before
+.Ql make !
+.Pp
+The one catch was that,
+having chdir'd in,
+I had to canonicalize the paths to any scripts used in the build recipes.
+For instance,
+I have a genpost.sh script in the
+.Pa bin/
+directory of this repo.
+To call it from the
+.Pa obj
+directory,
+I needed to use its absolute path via the
+.Va .CURDIR
+variable:
+.Pp
+.Dl $(.CURDIR)/bin/genpost.sh < $< > $@
+.Sh PORTABILITY
+While I mostly build my site on OpenBSD,
+it's important to me that it builds with GNU make too.
+.Pp
+Unfortunately,
+the
+.Va .OBJDIR
+chdir'ing appears to be an extension in OpenBSD's
+make (and possibly NetBSD too).
+The good news is that,
+with one more trick,
+GNU make support is easy to add
+(albeit without out-of-tree builds).
+.Pp
+The one final hack to support GNU make was to define
+a portable version of
+.Va .CURDIR .
+Since
+.Va .CURDIR
+isn't defined in GNU make (which uses
+.Va CURDIR
+instead),
+I had to define the
+.Va DIR
+variable that's the concatenation of the two:
+.Pp
+.Dl DIR = $(.CURDIR)$(CURDIR)
+.Pp
+.Sh CONCLUSION
+I hope this sheds some light on why
+.Ql make obj
+is common practice on OpenBSD as well as
+how to add similar support to your own projects!
+.Pp
+While not as flexible as GNU make's pattern matching
+inference rules (that allow builds in subdirectories),
+I find the chdir-ing into
+.Pa obj
+a cleverly simple way
+to obtain a similar end result.
+.Sh SEE ALSO
+.Bl -bullet -compact
+.It
+.Xr blog 7
+.It
+.Xr text-only 7
+.It
+.Xr my-old-man 7
+.El