Skip to content

Modify MLBs to build and test on polymlb as well#19

Merged
melsman merged 7 commits into
diku-dk:masterfrom
pzel:build-on-polymlb
Jun 18, 2026
Merged

Modify MLBs to build and test on polymlb as well#19
melsman merged 7 commits into
diku-dk:masterfrom
pzel:build-on-polymlb

Conversation

@pzel

@pzel pzel commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

I've been compiling this project with my own hacky branch made to support polymlb.

This PR is a cleaned-up version of my hacky code, with the following changes:

  1. smlpkg.mlb and futpkg.mlb now contain an extra call-main.sml file, which does the
    val _ = main () trick to launch the main function when compiled with MLton/MLKit.

  2. when MLCOMP is polymlb, the option to -ignore-call-main is used, so the produced executable will use the main function as defined in smlpkg.sml and futpkg.sml respectively.

  3. Tests were modified more heavily. I noticed that test failures did not bubble up to the OS, and the only way to see that a test was failing was to look at the output. I collected the duplicated code from the unit test files and made a test preamble and postamble. These are pre-pended and appended to the test suites, so any errors during evaluation get reported to the runner (make). After feedback, this is now implemented as a TestSuite() functor, opened in each test.sml suite. PolyMLB is instructed to use reportAndExit from the functor in lieu of main.

  4. The tests don't use the call-main trick, as I think it's overkill. In the case of tests, polymlb will just evaluate all the test cases as it "compiles" the executable, and if any tests fail, the "compilation" will abort, which signals an error code to make. If all the tests pass, the generated executable will always execute successfully, so it is in effect a witness to all the tests passing at comptime.

The test logic remains unchanged.

Test suite behavior remains unchanged under mlton/mlkit, save for the changes in point 3), which cause test failures to exit the suite with a nonzero code.

  1. futpkg and smlpkg now compile in a separate mlb tempdir on mlkit, as code-sharing call-main was erroring out the linker.

  2. There is now a PHONY make test-all-supported-compilers target which runs all tests in sequence under mlton, mlkit, and polymlb.

I'm open to fixes and suggestions, if you feel this work is not up to par.

Comment thread src/smlpkg.mlb Outdated
@@ -1,2 +1,3 @@
pkg.mlb
smlpkg.sml
call-main.sml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There might be a problem with MLKit's recompilation system having problems with the same file (call-main.sml) being part of multiple mlb-files... A solution may be to have two files instead - call-main.sml and call-main-futpkg.sml...

@pzel pzel Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thank you for the suggestion. That was indeed the cleaner solution, implemented in 2978dc9.

I used polymlb's default MLB annotation parameter to ignore both call-main's, so the compilation process uses the same .mlb files with all compilers.

Comment thread src/util/test.mlb Outdated
../test/preamble.sml
test.sml
test_system.sml
../test/postamble.sml

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be nicer to have a test.mlb file that features the test functionality, which may then be called from the individual test files? Would that work with PolyML - again, MLKit doesn't work well with sml-files being part of multiple mlb-files (mlb-files can mention other mlb-files, of course)...

@pzel pzel Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, thank you for the push on this. I was able to clean up the tests even further witout having to resort to multiple mlb files. What I did was:

  1. Create a TestSuite functor that keeps a local ref of test error count per instantiation.
  2. Load this functor definition via testSuite.mlb in each test.mlb
  3. Inside the tests themselves, instantiate and open the functor. This way the test bodies did not have to be refactored in any way
  4. Call reportAndExit (from the opened TestSuite struct) at the end of the test file.
  5. Have polymlb use reportAndExit as the main entrypoint, so we don't have to resort to call-main workarouds.
  6. I also extracted all the duplicated Makefile machinery to test.mk, and included it where appropriate.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still means that polymlb evaluates the test as it's being "compiled", but I think that's acceptable, since the tests value is in their being executed at some point during the run.

@pzel pzel force-pushed the build-on-polymlb branch from 847f157 to 2978dc9 Compare June 18, 2026 08:20
@athas

athas commented Jun 18, 2026

Copy link
Copy Markdown
Member

I think having smlpkg compile with PolyML is worth it for its own sake, but I'm curious: apart from demonstrating real-world portability of SML, is there a practical advantage to compiling smlpkg with PolyML?

@melsman melsman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

@pzel

pzel commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

On a complete sidenote, mlkit does not accept the Import filter syntax:

local
  $(SML_LIB)/basis/basis.mlb
  testSuite.sml
in
  functor TestSuite
end

It errors out with the message:

* Error: while parsing basis file 'testSuite.mlb' : I expect an 'end'(reached 'functor').
* Exiting!

Mlton and polymlb support this syntax as expected. In any case, I just export the full testSuite.sml in the mlb, and this works correctly and is semantically equivalent at this point, since that functor is the only thing defined in the file.

@pzel

pzel commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

@athas this whole effort is simply scratching a personal itch. I really only use PolyML for my personal programming, because of the rapid compilation and testing turnaround.

As I was trying to debug an issue I had with symlinks inside smlpkg dependencies, (solved here), I was really disheartened with how long it took to recompile the smlpkg binary to do printf-debugging.

So I went and got smlpkg compiling with polymlb and was able to really tighten the feedback loop and figure things out quickly. I decided to put up the PR as a contribution to the project, in case others are interested in using poly to develop smlpkg.

@melsman

melsman commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

On a complete sidenote, mlkit does not accept the Import filter syntax..

There are no plans for MLKit to support import filters...

@melsman melsman merged commit bfc9216 into diku-dk:master Jun 18, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants