28585, "dlongnecke-cray", "Giving the runtime library variants different base names", "2026-03-24T20:58:58Z"
This issue advocates for renaming Chapel's runtime variants to libchpl-static.a and libchpl.so.
Recently in #28359 we started generating two different versions of the Chapel runtime, libchpl.a and libchpl.so.
The first is a static archive that is used by 99.9% of all built Chapel programs, as traditionally the runtime is compiled into each Chapel application.
The second is a shared library which has been introduced as part of an effort to support dynamically loading Chapel programs. In the future, it may well become the standard way to use the Chapel runtime, though this is not an ironclad guarantee, and users will always be able to utilize a builtin runtime if they want.
However, as of #28359 some tests have started to fail. The reason they are failing is because in #28359 we started linking against the runtime using an absolute path instead of by throwing the -lchpl flag. This is to prevent any ambiguity on the part of the underlying linker.
Traditionally, when -l is thrown and a library name is overloaded (e.g., both .so and .a are available), the linker prefers to select the .so shared library variant. The Chapel compiler has to be able to precisely control which variant of the runtime is used for a particular compilation, so the behavior of preferring .so is not acceptable.
This behavior can be controlled via alternative linker flags (e.g., -l:, -start, -Bstatic -lchpl, -end), however these flags are not portable. Most of them are supported by GNU, some of them are supported by Clang, and basically none of them are supported on OSX when using the system linker.
What tests are breaking?
There are two test failure modes.
The first is an issue with Python interop. The Chapel compiler emits a .py file that constructs a setuptools.Extension. That API emits linker flags in a specific order that was causing "undefined symbol" issues. This bug is addressed via a (somewhat hacky) change. See: #28575
The second is that there is a test at test/gpu/native/interop/gpuLibrary which compiles a GPU test (via Makefile) by throwing -x cpp / -x cuda / -x hip, followed by a source, followed by compiler and linker flags. The direct path to libchpl.a is in those linker flags, and the C compiler used to compile the test treats that as a CPP source file.
I can live with the first change, but I don't think we have any leeway to change the second test to not throw -x as it is modeling a program that a user submitted. That means that it should probably continue to use the build assistance (compiler generated Makefile), along with the unaltered Makefile that the user wrote.
In both these cases, if we adjust the runtime names so that we can throw -l and have the specified runtime library be completely unambiguous, the issue is resolved. It is also a very simple (< 10 line) change to make. After exploring alternative options such as linker flags or using symlinks, this seems like the most simple, portable way to address the test failures and ensure things work smoothly going forward.
This is why I am advocating for us to consider naming our Chapel runtime libraries as:
libchpl-static.a: The static archive that is bundled into Chapel programs that need a builtin runtime
libchpl.so: The shared library that is installed and that users may see (e.g., when debugging)
But don't static/shared variants usually have the same names, sans extensions?
Yes, that's true. However, what this issue has revealed to me is that the problem doesnt' seem to be how the Chapel compiler links against its runtimes (99% of Chapel programs seem to compile just fine), it's how interop / extraneous consumers of Chapel libraries interact with the runtime.
The Chapel runtime isn't normally referenced directly by users. Even in interop, its use is usually wrapped behind a Makefile / CMake variable. It would be a rare thing to have a user specify a path to the runtime library directly. This is why not following convention doesn't bother me so much.
Note that libchpl-static.a is an archive, not a library. When a Chapel program is compiled with it, it does not persist in the way that libchpl.so would. So there is not really a chance that a user would ever see the name libchpl-static in a final product. So of the two runtime variants, it makes the most sense to rename.
Chapel has only used the static variant of the runtime for almost the entirety of its existence. So that means that before #28359, users have never really had to care about the name of the (static) runtime at all. They never interacted with it and never saw it in any capacity outside of it potentially showing up in the text of a (interop) build invocation.
However, libchpl.so is a shared library, and it will persist. All Chapel programs that load it will see libchpl.so when e.g., debugging or when inspecting what symbols belong to what program. So it makes sense that this should have the name we prefer and wish to show the world.