-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
make3: Toward a friendlier build system #12
base: master
Are you sure you want to change the base?
Conversation
It seems that meson build-system is getting momentum. It is faster, much easy to read than autotools/cmake, allows cross-platform builds, offers configurability with build options, etc. Maybe better to switch to it instead? |
Peter Lemenkov <[email protected]> wrote:
It seems that meson build-system is getting momentum. It is faster, [much easy to read](https://github.com/flashrom/flashrom/blob/master/meson.build) than autotools/cmake, allows cross-platform builds, offers configurability with [build options](https://github.com/flashrom/flashrom/blob/master/meson_options.txt), etc.
Maybe better to switch to it instead?
Thank you for the interest and suggestion.
Personally, I am wary of introducing any extra tooling unless there is a strong
case for its need. With any build system, the benefits need to be weighed
against the drawbacks. Do we really want to ask upstream J developers to learn
a whole new build system? Meson replaces make with ninja, so any users wanting
to compile J need ninja installed. Is that a reasonable tradeoff? Meson solves
a few specific bulid-related problems, but is jsource bumping up against those
problems? There is a plethora of options when it comes to build tooling, why
choose Meson, specifically?
Those are pretty big questions, especially since we currently only rely on bog
standard tooling. My bias in this project is a tad entish. Unless there are
concrete reasons to make a major change, it seems a bit hasty to overhaul
something that works. In this PR, I do try to make a case that motivates my
overhaul of the scripts. Whether or not that's a strong and relevant case is
for upstream to decide.
Also, it's important to remember that J isn't run like a community-driven
project. Upstream likely has concerns and requirements that are not obvious at
first glance. One reason I submitted this PR was to provide a concrete
demonstration of my idea so the J developers could have half a chance of
weighing it against those concerns of I have no knowledge of. If you feel
strongly about the Meson idea, then a similar approach might add valuable
material to this discussion.
Anyway, thank you again for the interest.
|
I think CMake is the only reasonable option. As a cross-platform build system generator, it has builtin support in Visual Studio, which proves its acceptance. |
CMake is an abomination, and should be avoided at all costs. Makefiles and scripts aren't inherently bad; they just need to be made friendlier. |
Makefiles and scripts are an abomination, and should be avoided at all costs. CMake isn't inherently bad; it just needs to be made friendlier. |
Somehow I/we missed your excellent J source PR#12.
My apologies. Is getting back to you after 18 months too ridiculous?
If you are still interested in J and cleaning up our make mess, I would
love to talk with you.
As you noted, Jsoftware's relationship to github/PR is close to zero. We
want to change that. We are probably going to switch from GPL to MIT or
ISC. And become more encouraging and responsive to PRs. But it won't happen
overnight.
I loved the bit I found under your reddit handle:
Wait no, those perturbative oblate spheroid people are even moreso
jackasses. The Earth is a dynamical system of Techtonic plates flowing over
a fluid mantle.
***
I am on unfamiliar ground here and am not sure this email will get to you.
Our guy who knows more about this stuff is away right now so I am flying
blind.
Would love to hear back from you (regular email).
…On Fri, Feb 14, 2020 at 11:32 PM xelxebar ***@***.***> wrote:
Overview
This PR is part of a larger goal to make J easier to package and share
across OSes and Linux distributions.
Currently, the make and make2 build systems provide a particularly
non-standard build process. They work well under their intended
environments but provide significant munging to work as part of other build
systems. This is due to the builds being largely managed by an ad-hoc
collection of scripts rather than relying on standard tooling.
My hope is that, at the very least, this initiates discussion toward
making J buildable and distributable in a more robust and friendly way.
Project Goal
Anecdotally, the current build system(s) provide significant challenges to
users simply wishing to try out J on their system. The overall goal is to
provide a build that uses the familiar and build-system-friendly make and,
if needed, autotools:
$ ./configure
$ make
$ make install
The collection of commits in this PR shares my initial progress in this
regard.
Specific Pain Points
In particular, the following is a collection of issues I have had to work
around in order to package J for the Void Linux distribution:
1. Sparse documentation
The build process is specific to J and highly non-standard. However, the
documentation introducing said process is limited to overview.txt and
make{,2}/make.txt which are both quite sparse. The existing documentation
works well under a limited set of build conditions, but there is little
information, either within the source tree or online, regarding how to make
the build fit your requirements. This is mostly a case of "the code is the
documentation."
1. Fragile logic for setting CFLAGS,
Currently, CFLAGS is set with -Werror and a collection of -W flags that
depends on whether the compiler is thought to be gcc or not. The
gcc-detection scheme relies on *ad hoc* path parsing and symlink
resolution which still breaks when using tools such as ccache. It is
possible to short-circuit the detection to your preferred compiler;
however, doing so is very non-trivial for someone not familiar with the
build scripts. Furthermore, assuming the compiler to be only gcc or clang
imposes an unexpected and artificial restriction that is decoupled from
where such requirements may actually originate.
1. Fails to respect CFLAGS, LDFLAGS *etc.* of environment,
When compiling as part of a larger build chain, it is standard to have
CFLAGS populated with options you wish all your compiles to pick up.
However, the build scripts in make and make2 clobber these environment
variables. This is unexpected bevahivour and requires careful modification
of the scripts to rectify.
1. Non-friendly "install",
By default, the build system simply builds. There is no equivalent of a make
install. Implicitly, the assumption is that the user will either run
jconsole directly from the build output directory or copy these to some
location, preserving the directory structure. This violates the
expectations of the Filesystem Hierarchy Standard (FHS) for installed
software on Unices and Linux distributions.
It is possible to manually pull apart the pieces and install J in a way
that follows the FHS; however, this requires editing profile.ijs and
providing (undocumented) flags to jconsole. This seems like an
unreasonably high barrier to entry for someone simply wishing to offer J as
a package for their favorite Linux distribution.
1. Intractible use of shell scripting, and
The build scripts, while functional, are overall in need of a lot of TLC.
There are deeply-nested if statements, giant case blocks with many
repeated elements, and a lot of custom path-munging via cd and pwd. These
techniques make the inherent logic within the scripts quite difficult to
follow and fail to leverage standard shell facilities that, ostensibly,
would perform the same job more concisely and robustly.
1. Undocumented build options.
As far as I can tell, apart from the standard build environment variables
the following allow the user to toggle various J-specific build options:
- USE_OPENMP,
- USE_LINENOISE,
- USE_THREAD,
- VERBOSELOG, and
- jolecom (?).
However, the only place these are documented is within thes scripts
themselves. Are these inteneded as undocumented/experimental options? If
they are inteded to be user-facing, it would make sense to keep track of
this kind of flag within make.txt at the very least.
What this PR does
I hope the above makes a case that the build system can be improved. I am
willing to lead the charge in that endeavor if upstream is on board.
At the moment, the collection of build scripts here do little to change
the above pain points, instead opting for a gradual and incremental
evolution of make2 into the inteded target. The HEAD of this PR contains
a new make3 directory, which is an exact copy of make2 at the start of
this branch (commit cb4d852
<cb4d852>
).
Within make3 I have only refactored build_jconsole.sh and build_libj.sh
into code that I hope is "better". I personally feel it's more grokkable,
and it reduces the SLOC count to about half of the originals.
I made an effort to ensure the changes are completely transparent by
confirming identical hashes of (a tar of) the build products. That said, I
have only confirmed this for linux and raspberry (under all j64x
targets). My plan is to do the same for android, windows and darwin if this
idea gains traction.
Notes
The make3 build should Just Work™ in exactly the same way as make2;
however, as per the comments regarding scripting style, I opted to make one
change to how build options are passed. Previously, each option was only
enabled if the associated variable was set to "1". The scripts now enable
each option if they are set to anything at all (other than the empty
string). USE_LINENOISE is the only exception, since it defaults to
enabled. You can disable as previously it by setting said variable to
anything other than "1".
Any other "API" differences are unintended.
Prologue
If you made it this far, thank you for reading through this long PR
explanation! If any of the above comes across as overly brash, please
accept my apologies. My head has been deep in the code and associated
frustrations for a while.
I look forward to hearing your feedback.
------------------------------
You can view, comment on, or merge this pull request online at:
#12
Commit Summary
- Start new make3 build directory
- make3:libj,jconsole: Print all exported variables
- make3:libj,jconsole: Replace `...` subshells with $(...)
- make3:libj,jconsole: Double quote parameters
- make3:libj,jconsole: Replace cd path hopping with explicit path
variables
- make3:libj,jconsole: Document GNUC_MINOR as unused
- make3:libj,jconsole: Set shell "strict mode"
- make3:jconsole: Disentagle control flow logic
- make3:libj: Refactor logic into orthogonal units
File Changes
- *A* make3/build_all.sh
<https://github.com/jsoftware/jsource/pull/12/files#diff-0> (38)
- *A* make3/build_jconsole.sh
<https://github.com/jsoftware/jsource/pull/12/files#diff-1> (109)
- *A* make3/build_jnative.sh
<https://github.com/jsoftware/jsource/pull/12/files#diff-2> (161)
- *A* make3/build_libj.sh
<https://github.com/jsoftware/jsource/pull/12/files#diff-3> (225)
- *A* make3/build_tsdll.sh
<https://github.com/jsoftware/jsource/pull/12/files#diff-4> (175)
- *A* make3/clean.sh
<https://github.com/jsoftware/jsource/pull/12/files#diff-5> (21)
- *A* make3/make.txt
<https://github.com/jsoftware/jsource/pull/12/files#diff-6> (42)
- *A* make3/makefile-jconsole
<https://github.com/jsoftware/jsource/pull/12/files#diff-7> (29)
- *A* make3/makefile-jnative
<https://github.com/jsoftware/jsource/pull/12/files#diff-8> (29)
- *A* make3/makefile-libj
<https://github.com/jsoftware/jsource/pull/12/files#diff-9> (185)
- *A* make3/makefile-tsdll
<https://github.com/jsoftware/jsource/pull/12/files#diff-10> (28)
Patch Links:
- https://github.com/jsoftware/jsource/pull/12.patch
- https://github.com/jsoftware/jsource/pull/12.diff
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#12?email_source=notifications&email_token=AEBRCHSZHRJVP4ZJAFOS46LRC5V5ZA5CNFSM4KVU4PO2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4INX2TDA>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEBRCHTLIM5Q6DY54D5KQVDRC5V5ZANCNFSM4KVU4POQ>
.
|
eiverson ***@***.***> wrote:
Somehow I/we missed your excellent J source PR#12.
My apologies. Is getting back to you after 18 months too ridiculous?
Hello Eric,
Thank you for the ping. Actually, I should probably be the one issuing
apologies!
IIRC, you responded at the time when I notified Jsource about the PR. Email
addresses are different, but I am one and the same person:
http://www.jsoftware.com/pipermail/source/2020-February/001299.html
If you are still interested in J and cleaning up our make mess, I would
love to talk with you.
I am definitely still interested! The intervening 18 months haven't
changed my intentions, but they have ended up changing my circumstances
(new job, getting married, building a house, etc.), so I very much left you
all hanging. Sorry about that!
In fact, a past me also started some thread expressing concern over JE's
conspicuous lack of contributors:
http://www.jsoftware.com/pipermail/programming/2021-February/057487.html
Hery quickly offered to help me get involved. I am still very interested in
this too!
As you noted, Jsoftware's relationship to github/PR is close to zero. We
want to change that. We are probably going to switch from GPL to MIT or
ISC. And become more encouraging and responsive to PRs. But it won't happen
overnight.
Very interesting. I am obviously unfamiliar with the constraints and
internal motivations that Jsoftware is dealing with, but I might be able
to offer a bit of experience with current norms in OSS dev communities,
FWIW.
I loved the bit I found under your reddit handle:
Wait no, those perturbative oblate spheroid people are even moreso
jackasses. The Earth is a dynamical system of Techtonic plates flowing over
a fluid mantle.
Haha. I had completely forgotten about that conversation. I am also
slightly mortified that such little coprolites from a past me are
lingering around, so easily excavated.
I am on unfamiliar ground here and am not sure this email will get to you.
Our guy who knows more about this stuff is away right now so I am flying
blind.
Would love to hear back from you (regular email).
Thank you again for expressing interest in that massive PR dump.
I am just on the last stretch of my house build, so I (naively?) expect
and hope that I will be able to settle into some semblance of a
life-rhythm in the near future. At that point I very much hope to get
back to J (and math).
On a more specific note, I recall you mentioning that you and the core team
are scattered between Canada, the U.S., and Hong Kong. Do you all directly
collaborate much? I badly want to hang out with and collaborate with some
hard-core array programmers, but my timezone in Japan makes attending JLUG
and similar meetups extremely difficult.
Anyway, if you have any questions, thoughts, or just wish to chat, I always
get a jolt of joy seeing a message from you in my inbox.
Cheers,
Brandon
… On Fri, Feb 14, 2020 at 11:32 PM xelxebar ***@***.***> wrote:
> Overview
>
> This PR is part of a larger goal to make J easier to package and share
> across OSes and Linux distributions.
>
> Currently, the make and make2 build systems provide a particularly
> non-standard build process. They work well under their intended
> environments but provide significant munging to work as part of other build
> systems. This is due to the builds being largely managed by an ad-hoc
> collection of scripts rather than relying on standard tooling.
>
> My hope is that, at the very least, this initiates discussion toward
> making J buildable and distributable in a more robust and friendly way.
> Project Goal
>
> Anecdotally, the current build system(s) provide significant challenges to
> users simply wishing to try out J on their system. The overall goal is to
> provide a build that uses the familiar and build-system-friendly make and,
> if needed, autotools:
>
> $ ./configure
>
> $ make
>
> $ make install
>
>
> The collection of commits in this PR shares my initial progress in this
> regard.
> Specific Pain Points
>
> In particular, the following is a collection of issues I have had to work
> around in order to package J for the Void Linux distribution:
>
> 1. Sparse documentation
>
> The build process is specific to J and highly non-standard. However, the
> documentation introducing said process is limited to overview.txt and
> make{,2}/make.txt which are both quite sparse. The existing documentation
> works well under a limited set of build conditions, but there is little
> information, either within the source tree or online, regarding how to make
> the build fit your requirements. This is mostly a case of "the code is the
> documentation."
>
> 1. Fragile logic for setting CFLAGS,
>
> Currently, CFLAGS is set with -Werror and a collection of -W flags that
> depends on whether the compiler is thought to be gcc or not. The
> gcc-detection scheme relies on *ad hoc* path parsing and symlink
> resolution which still breaks when using tools such as ccache. It is
> possible to short-circuit the detection to your preferred compiler;
> however, doing so is very non-trivial for someone not familiar with the
> build scripts. Furthermore, assuming the compiler to be only gcc or clang
> imposes an unexpected and artificial restriction that is decoupled from
> where such requirements may actually originate.
>
> 1. Fails to respect CFLAGS, LDFLAGS *etc.* of environment,
>
> When compiling as part of a larger build chain, it is standard to have
> CFLAGS populated with options you wish all your compiles to pick up.
> However, the build scripts in make and make2 clobber these environment
> variables. This is unexpected bevahivour and requires careful modification
> of the scripts to rectify.
>
> 1. Non-friendly "install",
>
> By default, the build system simply builds. There is no equivalent of a make
> install. Implicitly, the assumption is that the user will either run
> jconsole directly from the build output directory or copy these to some
> location, preserving the directory structure. This violates the
> expectations of the Filesystem Hierarchy Standard (FHS) for installed
> software on Unices and Linux distributions.
>
> It is possible to manually pull apart the pieces and install J in a way
> that follows the FHS; however, this requires editing profile.ijs and
> providing (undocumented) flags to jconsole. This seems like an
> unreasonably high barrier to entry for someone simply wishing to offer J as
> a package for their favorite Linux distribution.
>
> 1. Intractible use of shell scripting, and
>
> The build scripts, while functional, are overall in need of a lot of TLC.
> There are deeply-nested if statements, giant case blocks with many
> repeated elements, and a lot of custom path-munging via cd and pwd. These
> techniques make the inherent logic within the scripts quite difficult to
> follow and fail to leverage standard shell facilities that, ostensibly,
> would perform the same job more concisely and robustly.
>
> 1. Undocumented build options.
>
> As far as I can tell, apart from the standard build environment variables
> the following allow the user to toggle various J-specific build options:
>
> - USE_OPENMP,
> - USE_LINENOISE,
> - USE_THREAD,
> - VERBOSELOG, and
> - jolecom (?).
>
> However, the only place these are documented is within thes scripts
> themselves. Are these inteneded as undocumented/experimental options? If
> they are inteded to be user-facing, it would make sense to keep track of
> this kind of flag within make.txt at the very least.
> What this PR does
>
> I hope the above makes a case that the build system can be improved. I am
> willing to lead the charge in that endeavor if upstream is on board.
>
> At the moment, the collection of build scripts here do little to change
> the above pain points, instead opting for a gradual and incremental
> evolution of make2 into the inteded target. The HEAD of this PR contains
> a new make3 directory, which is an exact copy of make2 at the start of
> this branch (commit cb4d852
> <cb4d852>
> ).
>
> Within make3 I have only refactored build_jconsole.sh and build_libj.sh
> into code that I hope is "better". I personally feel it's more grokkable,
> and it reduces the SLOC count to about half of the originals.
>
> I made an effort to ensure the changes are completely transparent by
> confirming identical hashes of (a tar of) the build products. That said, I
> have only confirmed this for linux and raspberry (under all j64x
> targets). My plan is to do the same for android, windows and darwin if this
> idea gains traction.
> Notes
>
> The make3 build should Just Work™ in exactly the same way as make2;
> however, as per the comments regarding scripting style, I opted to make one
> change to how build options are passed. Previously, each option was only
> enabled if the associated variable was set to "1". The scripts now enable
> each option if they are set to anything at all (other than the empty
> string). USE_LINENOISE is the only exception, since it defaults to
> enabled. You can disable as previously it by setting said variable to
> anything other than "1".
>
> Any other "API" differences are unintended.
> Prologue
>
> If you made it this far, thank you for reading through this long PR
> explanation! If any of the above comes across as overly brash, please
> accept my apologies. My head has been deep in the code and associated
> frustrations for a while.
>
> I look forward to hearing your feedback.
> ------------------------------
> You can view, comment on, or merge this pull request online at:
>
> #12
> Commit Summary
>
> - Start new make3 build directory
> - make3:libj,jconsole: Print all exported variables
> - make3:libj,jconsole: Replace `...` subshells with $(...)
> - make3:libj,jconsole: Double quote parameters
> - make3:libj,jconsole: Replace cd path hopping with explicit path
> variables
> - make3:libj,jconsole: Document GNUC_MINOR as unused
> - make3:libj,jconsole: Set shell "strict mode"
> - make3:jconsole: Disentagle control flow logic
> - make3:libj: Refactor logic into orthogonal units
>
> File Changes
>
> - *A* make3/build_all.sh
> <https://github.com/jsoftware/jsource/pull/12/files#diff-0> (38)
> - *A* make3/build_jconsole.sh
> <https://github.com/jsoftware/jsource/pull/12/files#diff-1> (109)
> - *A* make3/build_jnative.sh
> <https://github.com/jsoftware/jsource/pull/12/files#diff-2> (161)
> - *A* make3/build_libj.sh
> <https://github.com/jsoftware/jsource/pull/12/files#diff-3> (225)
> - *A* make3/build_tsdll.sh
> <https://github.com/jsoftware/jsource/pull/12/files#diff-4> (175)
> - *A* make3/clean.sh
> <https://github.com/jsoftware/jsource/pull/12/files#diff-5> (21)
> - *A* make3/make.txt
> <https://github.com/jsoftware/jsource/pull/12/files#diff-6> (42)
> - *A* make3/makefile-jconsole
> <https://github.com/jsoftware/jsource/pull/12/files#diff-7> (29)
> - *A* make3/makefile-jnative
> <https://github.com/jsoftware/jsource/pull/12/files#diff-8> (29)
> - *A* make3/makefile-libj
> <https://github.com/jsoftware/jsource/pull/12/files#diff-9> (185)
> - *A* make3/makefile-tsdll
> <https://github.com/jsoftware/jsource/pull/12/files#diff-10> (28)
>
> Patch Links:
>
> - https://github.com/jsoftware/jsource/pull/12.patch
> - https://github.com/jsoftware/jsource/pull/12.diff
>
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub
> <#12?email_source=notifications&email_token=AEBRCHSZHRJVP4ZJAFOS46LRC5V5ZA5CNFSM4KVU4PO2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4INX2TDA>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AEBRCHTLIM5Q6DY54D5KQVDRC5V5ZANCNFSM4KVU4POQ>
> .
>
--
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub:
#12 (comment)
|
813e45e
to
c3204a6
Compare
31a893e
to
c42aa42
Compare
@xelxebar you may find my build scripts (modifications to make2) helpful in constructing make3. I broke arm, and never got around to fixing it; but the core logic is largely factored, and hence much easier to change and understand. |
@moon-chilled Cool. It looks like some of your factoring went in a similar direction as my original (now clobbered) commits. Thanks for sharing. I might have a closer look later. |
c6377af
to
1528769
Compare
5b6e7be
to
830c1dc
Compare
c695434
to
f379f4c
Compare
The goal is to provide a build process that is friendly to package maintainers for arbitrary Linux distributions, while maintaining the current status quo for non-Linux targets. In particular, the project aims to improved the following perceived deficiences of current make2: 1. Ad-hoc, idiosyncratic shell scripts; 2. Fragile custom code for compiler detection; 3. Ignores host's CFLAGS, LDFLAGS etc; 4. Non-obvious availability of other build flags, e.g. `USE_OPENMP` etc; 5. Non-error exit code on failure; 6. Unsavory reputation amongst existing package maintainers. The above issues are adressable by updates to the build scripts alone. However, there are further issues that require supporting changes elsewhere: 7. Build non-determinism (due to `__DATE__` and `__TIME__` macro usage); 8. Hostile to FHS-conforming installs. Importantly, in the course of working on the above, we impose some important constraints on ourself: 1. Build system changes must not introduce unintended changes in build products; 2. The current, officially supported build environments must not be broken; 3. Changes should be as conservative as possible to achieve goals. This commit introduces a temporary meta-build tool, `jbuild.scm`, to help maintain the above mentioned constraints. See that file for details.
Executing jbuild.scm as a script will build J from source, hash the output, and display the result, with a comparison against a known good target hash. Note that, unfortunately, the diff in this commit got mixed with a large re-indentation fix, but the bulk of semantic changes take place below the `;;; Execution' section.
Our starting point for make3 is make2. We anticipate that trialing make3 will necessitate it sitting parallel to make3, at least temporarily, and so have opted to copy make2 instead of munging it directly.
Unfortunately, we ran into build non-determinism, causing random target-hash mismatches. In particular, we noticed this when a hash mismatch fired after removing some dead code from build_jconsole.sh. By diffing the xtrace, i.e. `set +x`, results with and without the change, we confirmed that the executed commands were exactly the same; however, a quick inspection using diffoscope on the two output directories revealed differences, not in jconsole, but in libj.so. The issue seems to be that build outputs are colocated with source files, meaning that parallel builds end up clobbering each other's object files.
For 100% build reproducibility we also need to ensure that we build against a stable set of dependencies. This commit defines an explicit guix channel revision against which the build script runs. In particular, without an explicit channel revision and when run on different machines, the build script is likely to produce different outputs, causing a mismatch with the target hash. In fact, the same may happen on a single machine, if invoked across `guix pull` updates.
Much ink has been spilled over the "correct" shebang. Here, opting for env-style is making a declaration of *intent*: These scripts prioritize environment flexiblity over execution precision. In particular, using a `#!/bin/sh` shebang declares that this script shall be run by the interpreter sitting at the absolute path `/bin/sh`. This style of shebang is useful when needing precise control over the executing interpreter. However, the use case for these scripts means that we have little a priori control over the executing interpreter, and there are legitimate cases where users may wish to use some other shell in preference to `/bin/sh`, e.g. containerized environments. The `#!/usr/bin/env sh` shebang caters to these needs. Of course, there are some cases (quite rare, now) where the env-shebang in this commit will fail [0]; however, we make the decision to de-prioritize these cases over the aforementioned ones. [0]:https://www.in-ulm.de/~mascheck/various/shebang/#env
Overview
This PR is part of a larger goal to make J easier to package and share across OSes and Linux distributions.
Currently, the
make
andmake2
build systems provide a particularly non-standard build process. They work well under their intended environments but provide significant munging to work as part of other build systems. This is due to the builds being largely managed by an ad-hoc collection of scripts rather than relying on standard tooling.My hope is that, at the very least, this initiates discussion toward making J buildable and distributable in a more robust and friendly way.
Project Goal
Anecdotally, the current build system(s) provide significant challenges to users simply wishing to try out J on their system. The overall goal is to provide a build that uses the familiar and build-system-friendly make and, if needed, autotools:
The collection of commits in this PR shares my initial progress in this regard.
Specific Pain Points
In particular, the following is a collection of issues I have had to work around in order to package J for the Void Linux distribution:
The build process is specific to J and highly non-standard. However, the documentation introducing said process is limited to
overview.txt
andmake{,2}/make.txt
which are both quite sparse. The existing documentation works well under a limited set of build conditions, but there is little information, either within the source tree or online, regarding how to make the build fit your requirements. This is mostly a case of "the code is the documentation."Currently,
CFLAGS
is set with-Werror
and a collection of-W
flags that depends on whether the compiler is thought to be gcc or not. The gcc-detection scheme relies on ad hoc path parsing and symlink resolution which still breaks when using tools such asccache
. It is possible to short-circuit the detection to your preferred compiler; however, doing so is very non-trivial for someone not familiar with the build scripts. Furthermore, assuming the compiler to be only gcc or clang imposes an unexpected and artificial restriction that is decoupled from where such requirements may actually originate.CFLAGS
,LDFLAGS
etc. of environment,When compiling as part of a larger build chain, it is standard to have
CFLAGS
populated with options you wish all your compiles to pick up. However, the build scripts inmake
andmake2
clobber these environment variables. This is unexpected bevahivour and requires careful modification of the scripts to rectify.By default, the build system simply builds. There is no equivalent of a
make install
. Implicitly, the assumption is that the user will either runjconsole
directly from the build output directory or copy these to some location, preserving the directory structure. This violates the expectations of the Filesystem Hierarchy Standard (FHS) for installed software on Unices and Linux distributions.It is possible to manually pull apart the pieces and install J in a way that follows the FHS; however, this requires editing
profile.ijs
and providing (undocumented) flags tojconsole
. This seems like an unreasonably high barrier to entry for someone simply wishing to offer J as a package for their favorite Linux distribution.The build scripts, while functional, are overall in need of a lot of TLC. There are deeply-nested
if
statements, giantcase
blocks with many repeated elements, and a lot of custom path-munging viacd
andpwd
. These techniques make the inherent logic within the scripts quite difficult to follow and fail to leverage standard shell facilities that, ostensibly, would perform the same job more concisely and robustly.As far as I can tell, apart from the standard build environment variables the following allow the user to toggle various J-specific build options:
USE_OPENMP
,USE_LINENOISE
,USE_THREAD
,VERBOSELOG
, andjolecom
(?).However, the only place these are documented is within thes scripts themselves. Are these inteneded as undocumented/experimental options? If they are inteded to be user-facing, it would make sense to keep track of this kind of flag within
make.txt
at the very least.What this PR does
I hope the above makes a case that the build system can be improved. I am willing to lead the charge in that endeavor if upstream is on board.
At the moment, the collection of build scripts here do little to change the above pain points, instead opting for a gradual and incremental evolution of
make2
into the inteded target. TheHEAD
of this PR contains a newmake3
directory, which is an exact copy ofmake2
at the start of this branch (commit cb4d852).Within
make3
I have only refactoredbuild_jconsole.sh
andbuild_libj.sh
into code that I hope is "better". I personally feel it's more grokkable, and it reduces the SLOC count to about half of the originals.I made an effort to ensure the changes are completely transparent by confirming identical hashes of (a tar of) the build products. That said, I have only confirmed this for linux and raspberry (under all
j64x
targets). My plan is to do the same for android, windows and darwin if this idea gains traction.Notes
The
make3
build should Just Work™ in exactly the same way asmake2
; however, as per the comments regarding scripting style, I opted to make one change to how build options are passed. Previously, each option was only enabled if the associated variable was set to "1". The scripts now enable each option if they are set to anything at all (other than the empty string).USE_LINENOISE
is the only exception, since it defaults to enabled. You can disable as previously it by setting said variable to anything other than "1".Any other "API" differences are unintended.
Prologue
If you made it this far, thank you for reading through this long PR explanation! If any of the above comes across as overly brash, please accept my apologies. My head has been deep in the code and associated frustrations for a while.
I look forward to hearing your feedback.