Make the autogenerated LIBS variable optionally-set#81
Open
pzel wants to merge 1 commit intosmlsharp:masterfrom
Open
Make the autogenerated LIBS variable optionally-set#81pzel wants to merge 1 commit intosmlsharp:masterfrom
pzel wants to merge 1 commit intosmlsharp:masterfrom
Conversation
This PR modifies the Makefile generated by `smlsharp -Mmm` so that the `LIBS`
env var is set to the empty string only if it isn't already present in the
environment.
This allows for setting the LIBS variable on a higher level than in the
Makefiles autogenerated by `smlsharp -Mmm`, therefore relieving the programmer
from having to manually (re)edit them upon (re)generation.
Rationale
---------
The rationale for this change is as follows. As far as I understand, `smlsharp`
leverages the mechanisms in POSIX make to ensure that particular `.sml` files
are compiled in the dependency order that is defined by their corresponding
`.smi` files.
When working on a codebase that often changes, it's convenient to treat the
`Makefile` as generated by `smlsharp -Mmm` as a transient file, and drive the
project's compilation process from a top-level `Makefile` (or some other
scripting/build system). This is especially the case when we also want to
support compiling our own C files via `make`.
Now, let's say we're compiling a `local.so` shared library in the top-level
Makefile. This entails
1) Setting up the top-level Makefile to compile `local.c` to `local.so`
2) Manually editing the autogenerated Makefile and changing the line
```
LIBS =
```
to
```
LIBS = local.so
```
Now, whenever we change the smlsharp side of the project and wish to regenerate
the smlsharp Makefile, we have to either a) always remember to go back and
hand-edit the `LIBS` variable assignment; or b) write some kind of sed script
to substitute the line in the autogenerated Makefile.
If the autogenerated Makefile used the conditional assignment operator `?=`, we
would only have to modify our top-level Makefile if we made changes to our C
libraries, whereas the lower-level Makefile autogenerated by smlsharp could be
safely regenerated as often as necessary without manual intervention.
This change modifies the `LIBS = ` line to `LIBS ?= ` in order to support this.
Example
-------
Below is an example project that showcases the situation
```
% ls
libsqr.c main.smi main.sml Makefile
% tail -n100 ./*
==> ./libsqr.c <==
short sqrShort (short n) { return (n * n); }
double sqrDouble (double n) { return (n * n); }
==> ./main.smi <==
_require "basis.smi";
==> ./main.sml <==
val sqrShort = _import "sqrShort" : int16 -> int16
val _ = print (Int16.toString (sqrShort 16) ^ "\n")
==> ./Makefile <==
LIBS=libsqr.so
all0: libsqr.so Makefile.smlsharp all
libsqr.so: libsqr.c
gcc -shared -fPIC $< -o $@
Makefile.smlsharp: $(shell find . | grep '.smi$$')
smlsharp -MMm main.smi > $@
include Makefile.smlsharp
```
The autogenerated `Makefile.smlsharp` gets included into our top-level project
Makefile, and should inherit the `LIBS` variable we set up on the first line of
the top-level Makefile.
We can simply call `make` to have:
1) all our C libraries compiled and linked before any smlsharp code
2) the linked libraries defined in one place only
3) `Makefile.smlsharp` regenerated if anything has changes in our smlsharp
dependency tree
```
% make && ./main
smlsharp -MMm main.smi > Makefile.smlsharp
gcc -shared -fPIC libsqr.c -o libsqr.so
smlsharp -O2 -o main.o -c main.sml
smlsharp -o main main.smi libsqr.so
256
```
And if we change something on the smlsharp side of things, the same command
works without having to manually re-edit `Makefile.smlsharp`
```
% echo '_require "reify.smi"' >> ./main.smi
% echo 'val _ = Dynamic.pp "All done"' >> ./main.sml
% make
smlsharp -MMm main.smi > Makefile.smlsharp
smlsharp -O2 -o main.o -c main.sml
smlsharp -o main main.smi libsqr.so
% ./main
256
"All done"
```
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR modifies the Makefile generated by
smlsharp -Mmmso that theLIBSenv var is set to the empty string only if it isn't already present in the environment.This allows for setting the LIBS variable on a higher level than in the Makefiles autogenerated by
smlsharp -Mmm, therefore relieving the programmer from having to manually (re)edit them upon (re)generation.Rationale
The rationale for this change is as follows. As far as I understand,
smlsharpleverages the mechanisms in POSIX make to ensure that particular.smlfiles are compiled in the dependency order that is defined by their corresponding.smifiles.When working on a codebase that often changes, it's convenient to treat the
Makefileas generated bysmlsharp -Mmmas a transient file, and drive the project's compilation process from a top-levelMakefile(or some other scripting/build system). This is especially the case when we also want to support compiling our own C files viamake.Now, let's say we're compiling a
local.soshared library in the top-level Makefile. This entailslocal.ctolocal.so2) Manually editing the autogenerated Makefile and changing the lineto
Now, whenever we change the smlsharp side of the project and wish to regenerate the smlsharp Makefile, we have to either a) always remember to go back and hand-edit the
LIBSvariable assignment; or b) write some kind of sed script to substitute the line in the autogenerated Makefile.If the autogenerated Makefile used the conditional assignment operator
?=, we would only have to modify our top-level Makefile if we made changes to our C libraries, whereas the lower-level Makefile autogenerated by smlsharp could be safely regenerated as often as necessary without manual intervention.This change modifies the
LIBS =line toLIBS ?=in order to support this.Example
Below is an example project that showcases the situation
The autogenerated
Makefile.smlsharpgets included into our top-level project Makefile, and should inherit theLIBSvariable we set up on the first line of the top-level Makefile.We can simply call
maketo have:Makefile.smlsharpregenerated if anything has changed in our smlsharp dependency treeAnd if we change something on the smlsharp side of things, the same command works without having to manually re-edit
Makefile.smlsharp