Skip to content

Relative paths of extra-include-dirs and extra-lib-dirs are resolved from each package's root instead of current working directory #11736

@sergv

Description

@sergv

TLDR

Relative paths in command line flags --extra-include-dirs, --extra-lib-dirs and their counterparts in cabal.project resolved against each package's root which causes surprising and user-unfriendly build errors.

Details

I created following repository to reproduce: https://github.com/random-random-stuff/test-cabal-relative-extra-include-and-lib-dirs and guide the following explanation.

I have a package cabal-test-dependency which wraps a foreign library. When building it a cabal_test_foo.h header and a libcabal_test_foo.so file must be available.

Then I have my main package cabal-test-main that uses cabal-test-dependency:

packages:
  cabal-test-main.cabal
  ../dependency/cabal-test-dependency.cabal

The directory with cabal-test-main is where I, as a user, is working in and is where I’m calling cabal from.

I have local copy of .h and .so that are needed to complete the build in root of cabal-test-main package under directory deps (in this though experiment a user puts .so where needed beforehand like here).

$ ls deps/
cabal_test_foo.c  cabal_test_foo.h  libcabal_test_foo.so

Now from cabal-test-main root I’m calling cabal build and pass deps/ directory so that dependency would build but the build fails:

$ cabal build --extra-lib-dirs deps --extra-include-dirs deps
Resolving dependencies...
Build profile: -w ghc-9.14.1 -O1
In order, the following will be built (use -v for more details):
 - cabal-test-dependency-0.1 (lib) (first run)
 - cabal-test-main-0.1 (exe:main) (first run)
Configuring library for cabal-test-dependency-0.1...
Warning: [unknown-directory] 'extra-lib-dirs: deps' specifies a directory
which does not exist.
Warning: [unknown-directory] 'include-dirs: deps' specifies a directory which
does not exist.
Error: [Cabal-4345]
Missing dependency on a foreign library:
* Missing (or bad) header file: cabal_test_foo.h
* Missing (or bad) C library: cabal_test_foo
If the header file does exist, it may contain errors that are caught by the C compiler at the preprocessing stage. In this case you can re-run 'Setup configure' with the verbosity flag -v3 to see the error messages.
Error: [Cabal-7125]
Failed to build cabal-test-dependency-0.1 (which is required by exe:main from cabal-test-main-0.1). The failure occurred during the configure step.

The errors are

Warning: [unknown-directory] 'extra-lib-dirs: deps' specifies a directory
which does not exist.
Warning: [unknown-directory] 'include-dirs: deps' specifies a directory which
does not exist.

apparently because deps directory is being resolved under root directory of cabal-test-dependency package where it does not exist.

If I specify absolute paths, e.g. cabal build --extra-lib-dirs "$(pwd)/deps" --extra-include-dirs "$(pwd)/deps" then build succeeds.

It seems like relative paths should work too and should resolve against where user is currently situated. For command line options that would be the current working directory and for cabal.project options it seems the location of the cabal.project file should serve as a root to resolve relative paths against.

According to #2641 the relative paths for extra-include-dirs and extra-lib-dirs are allowed but neither that PR nor manual provide concrete information as to how relative paths are resolved.

Current behavior seems like an artefact of the implementation where extra-include-dirs and extra-lib-dirs are added to each package’s include-dirs and library-dirs respectively and only then are resolved in each package’s context.

It does not seems like a good idea that that standing in package A and specifying a path relative to A’s root, e.g. foo/ results in dependent package B getting a relative foo/ directory in any part of its package description. While looking at A the user has no visibility under package B and what directories it contains.

System information

  • Operating system - Linux x86_64
  • cabal - 3.17.0.0, built from master, ghc - 9.14.1

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions