Skip to content
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

Setting --libsubdir without $libname leads to failure with auto-generated modules (Paths*) #10687

Open
Vekhir opened this issue Dec 29, 2024 · 1 comment

Comments

@Vekhir
Copy link

Vekhir commented Dec 29, 2024

Describe the bug
Setting --libsubdir without using $libname in combination with autogenerated Paths_* files leads to the generated files being copied to the same absolute path, therefore overwriting each other. The actual error doesn't occur until a dependent package wants to access the overwritten file.
Leaving it away entirely does not produce the bug, as the default is $abi/$libname.
More details in the top comment below.

To Reproduce
Example project is https://github.com/haskell/happy.

$ cd lib/
$ runhaskell Setup configure --libsubdir=""
$ runhaskell Setup build
$ runhaskell Setup copy --destdir="/tmp"
$ tree /tmp/usr/lib
$ cd ..
$ runhaskell Setup configure --libsubdir=""
$ runhaskell Setup build

For GHC 9.4+, the latter run fails at the build step, as happy cannot access the overwritten Paths_happy_lib file.
In earlier versions (GHC 9.2 and before), only a warning is emitted. This has been tightened to an error in GHC 9.4 and later.

Expected behavior
Cabal should warn about duplicate modules (the Paths_happy_lib module). Ideally, it wouldn't even produce two different modules, instead relying on the same Paths_* module.

System information
OS: Arch Linux
Kernel: Linux 6.12.7-arch1-1
GHC: 9.2.8, 9.4.8, 9.6.6, (9.8.2)
Cabal: 3.6, 3.8, 3.10
happy: 2.0.2, 2.1.3

Additional context
Related issues:
haskell/happy#328
#8733
hackage-cli also uses autogen-modules.

Arch package: build instructions

Log (haskell-happy-lib with extended debug logs)
with --libsubdir=\$compiler/site-local/\$pkgid

without --libsubdir

@Vekhir
Copy link
Author

Vekhir commented Jan 4, 2025

After further investigation, I now understand the structure better. As always, any hints are welcome.

What Setup copy does for sublibraries is quite simple: Take the compiled files from the build directory and put them in $libdir/$libsubdir. This part is correct.
The structure in the build directory is such that each sublibrary gets its own directory. In the case of happy-lib 2.1.3, this means that both backend-glr and backend-lalr can get their own Paths_happy_lib without issue. That auto-generated file has the same generic path within each.
But if $libname isn't used in the libsubdir, both sublibraries get merged as the paths of their modules are independent of the sublibrary. Therefore, one Paths_happy_lib overwrites the other. The default configuration (without specifying --libsubdir is $abi/$libname, so doesn't have this issue.

An attempt to resolve this duplication was to move the Paths_happy_lib generation into it own sublibrary (so it exists only once) and then make the other two depend on it. In a certain configuration, I then got the Duplicate modules in library error. Not quite sure why, probably because both sublibraries exposed this file (despite it being identical).
This error makes sense in the current context: If there was a duplicate module, there can't be a guarantee that after moving it, it still exists. In fact, they will overwrite each other.

Particularly interesting is that the Paths_happy_lib module is actually identical for each sublibrary afaict (the .hs is always identical by SHA-256 hash). If this is wrong, please correct me.

So we have two issues:

  1. The more immediate one is a missing warning for either the Paths_happy_lib module in particular or auto-generated files in general if they result in duplicate modules
  2. Avoid duplicate Paths_happy_lib modules

The first one is informational, the second one is a fix. However, I don't know whether it is possible to combine the auto-generation such that every sublibrary depending on it actually depends on the exact same file. In that case, overwriting wouldn't be an issue.

Any thoughts are appreciated.
-- Vekhir

@Vekhir Vekhir changed the title Setup copy produces weird directory structure with --libsubdir set during Setup configure Setting --libsubdir without $libname leads to failure with auto-generated modules (Paths*) Jan 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant