conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
8.31k stars 986 forks source link

[bug] src\meson.build:1:0: ERROR: prefix value '/' must be an absolute path #17204

Closed shoeffner closed 1 month ago

shoeffner commented 1 month ago

Describe the bug

When calling meson.configure() on Windows, it fails as meson considers the --prefix=/ as not being absolute on Windows. This is briefly theorized about in issue https://github.com/mesonbuild/meson/issues/12880 which is referenced in the code, but unfortunately the assumption to set / as the prefix turns out to be wrong for Windows:

18:19:38  inih/58: RUN: meson setup --native-file "C:\conan_cache\b\inihdc984b83cfbdd\b\build\generators\conan_meson_native.ini" "C:\conan_cache\b\inihdc984b83cfbdd\b\build" "C:\conan_cache\inih574f2c03001fa\s\src" --prefix=/
18:19:38  conanvcvars.bat: Activating environment Visual Studio 17 - amd64 - winsdk_version=None - vcvars_ver=14.4
18:19:39  [vcvarsall.bat] Environment initialized for: 'x64'
18:19:40  [vcvarsall.bat] Environment initialized for: 'x64'
18:19:40  The Meson build system
18:19:40  Version: 1.6.0
18:19:40  Source dir: C:\conan_cache\inih574f2c03001fa\s\src
18:19:40  Build dir: C:\conan_cache\b\inihaa284fe8813d4\b\build
18:19:40  Build type: native build
18:19:40  
18:19:40  ..\..\..\..\inih574f2c03001fa\s\src\meson.build:1:0: ERROR: prefix value '/' must be an absolute path
18:19:40  
18:19:40  A full log can be found at C:\conan_cache\b\inihaa284fe8813d4\b\build\meson-logs\meson-log.txt

Replacing / with C:\ fixes it, however! One way to achieve this is to use f' --prefix={os.path.abspath("/")}' instead of the plain /. Another option is os.path.abspath('.').split(os.path.sep)[0]+os.path.sep from stackoverflow, but I believe os.path.abspath should be sufficient and work on all relevant OSs.

Conan versions: Tested with 2.4.1 and 2.8.1, also checked source from develop2 branch and it's still there OS: Windows (Container: mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-ltsc2022) Meson: 1.6.0

How to reproduce it

This is a (not-so-minimal-but-)working example recipe. It's a bit convoluted as I extracted the bits and pieces from our shared code base etc., but in general it's enough to run any meson.configure() on Windows to trigger the error.

from conan import ConanFile
from conan.tools.meson import Meson, MesonToolchain
from conan.tools.cmake import cmake_layout
from conan.tools.files import collect_libs
from conan.tools.scm import Git

class Recipe(ConanFile):
    name = "inih"
    version = "58"
    url = "https://github.com/benhoyt/inih.git"
    package_type = "shared-library"
    settings = "os", "compiler", "build_type", "arch"
    options = {"fPIC": [True, False], "shared": [True, False]}

    def config_options(self):
        if self.settings.get_safe("os") == "Windows":
            self.options.rm_safe("fPIC")
        else:
            self.options.fPIC = True
        self.options.shared = True

    def generate(self):
        tc = MesonToolchain(self)
        tc.project_options["with_INIReader"] = True
        tc.project_options["distro_install"] = True
        if self.settings.os == "Windows":
            tc.project_options["default_library"] = "shared"
        tc.generate()

    def layout(self):
        cmake_layout(self, src_folder="src")

    def source(self):
        git = Git(self)
        git.clone(
            self.url,
            ".",
            ["--branch", f"r{self.version}", "--depth", "1"],
            hide_url=False,
        )

    def build(self):
        meson = Meson(self)
        meson.configure()
        meson.build()

    def package(self):
        meson = Meson(self)
        meson.install()

    def package_info(self):
        self.cpp_info.libs = collect_libs(self)
shoeffner commented 1 month ago

Thinking about my solution, I am not sure if it works for cross-compilations, as I do not know exactly how the prefix affects the whole build process – if the prefix is for the host, this should be fine – if it's for the target, this should maybe become something like:

"/" if target is not windows else r"C:\"

Do you have any insights on that?

memsharded commented 1 month ago

Hi @shoeffner

Thanks for your report.

Trying to reproduce. I had to change a small thing with ["--branch", f"r{self.version}", "--depth", "1"], Note the self.version

Then running conan create . works fine here in my Windows. Not failing as you report. Meson version 1.3.2 initially, but I also updated to 1.6 and it didn't fail. Not sure what could be the difference, are you sure you tried with the exact conanfile.py above? (because of the self.version thing, maybe you were running with a different recipe?)

shoeffner commented 1 month ago

I also had that issue with the version, sorry, forgot to update the code here...

Here is my full log with the now updated code:

======== Exporting recipe to the cache ========
inih/58: Exporting package recipe: C:\thirdparty\recipes\inih2\conanfile.py
inih/58: Copied 1 '.py' file: conanfile.py
inih/58: Exported to cache folder: C:\conan_cache\inih85aa9f97f39a3\e
inih/58: Exported: inih/58#71c40120e8f62e2c3258ec6ec69eefe4 (2024-10-23 09:55:55 UTC)
"conanfile.py" 52L, 1538B written
======== Input profiles ========
Profile host:
[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=17
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.version=194
os=Windows
[conf]
tools.build:jobs=30
tools.build:skip_test=true
tools.microsoft.msbuild:max_cpu_count=30
tools.system.package_manager:mode=report

Profile build:
[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=17
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.version=194
os=Windows
[conf]
tools.build:jobs=30
tools.build:skip_test=true
tools.microsoft.msbuild:max_cpu_count=30
tools.system.package_manager:mode=report

======== Computing dependency graph ========
Graph root
    cli
Requirements
    inih/58#71c40120e8f62e2c3258ec6ec69eefe4 - Cache

======== Computing necessary packages ========
inih/58: Forced build from source
Requirements
    inih/58#71c40120e8f62e2c3258ec6ec69eefe4:96b926a9076222d94071f3c1b1f5269cc834337a - Build

======== Installing packages ========

-------- Installing package inih/58 (1 of 1) --------
inih/58: Building from source
inih/58: Package inih/58:96b926a9076222d94071f3c1b1f5269cc834337a
inih/58: Copying sources to build folder
inih/58: Building your package in C:\conan_cache\b\iniha410db4cfe449\b
inih/58: Calling generate()
inih/58: Generators folder: C:\conan_cache\b\iniha410db4cfe449\b\build\generators
inih/58: Generating aggregated env files
inih/58: Generated aggregated env files: ['conanbuild.bat', 'conanrun.bat']
inih/58: Calling build()
inih/58: Meson configure cmd: meson setup --native-file "C:\conan_cache\b\iniha410db4cfe449\b\build\generators\conan_meson_native.ini" "C:\conan_cache\b\iniha410db4cfe449\b\build" "C:\conan_cache\b\iniha410db4cfe449\b\src" --prefix=/
inih/58: RUN: meson setup --native-file "C:\conan_cache\b\iniha410db4cfe449\b\build\generators\conan_meson_native.ini" "C:\conan_cache\b\iniha410db4cfe449\b\build" "C:\conan_cache\b\iniha410db4cfe449\b\src" --prefix=/
conanvcvars.bat: Activating environment Visual Studio 17 - amd64 - winsdk_version=None - vcvars_ver=14.4
[vcvarsall.bat] Environment initialized for: 'x64'
The Meson build system
Version: 1.6.0
Source dir: C:\conan_cache\b\iniha410db4cfe449\b\src
Build dir: C:\conan_cache\b\iniha410db4cfe449\b\build
Build type: native build

..\src\meson.build:1:0: ERROR: prefix value '/' must be an absolute path

A full log can be found at C:\conan_cache\b\iniha410db4cfe449\b\build\meson-logs\meson-log.txt

inih/58: ERROR:
Package '96b926a9076222d94071f3c1b1f5269cc834337a' build failed
inih/58: WARN: Build folder C:\conan_cache\b\iniha410db4cfe449\b\build
ERROR: inih/58: Error in build() method, line 44
        meson.configure()
        ConanException: Error 1 while executing

Once I fix the meson.py to use cmd += " --prefix=C:\\", it works.

shoeffner commented 1 month ago

Just for completeness, this is how the working configure step looks like:

inih/58: Calling build()
inih/58: Meson configure cmd: meson setup --native-file "C:\conan_cache\b\inih555089f1c99b5\b\build\generators\conan_meson_native.ini" "C:\conan_cache\b\inih555089f1c99b5\b\build" "C:\conan_cache\b\inih555089f1c99b5\b\src" --prefix=C:\
inih/58: RUN: meson setup --native-file "C:\conan_cache\b\inih555089f1c99b5\b\build\generators\conan_meson_native.ini" "C:\conan_cache\b\inih555089f1c99b5\b\build" "C:\conan_cache\b\inih555089f1c99b5\b\src" --prefix=C:\
conanvcvars.bat: Activating environment Visual Studio 17 - amd64 - winsdk_version=None - vcvars_ver=14.4
[vcvarsall.bat] Environment initialized for: 'x64'
The Meson build system
Version: 1.6.0
Source dir: C:\conan_cache\b\inih555089f1c99b5\b\src
Build dir: C:\conan_cache\b\inih555089f1c99b5\b\build
Build type: native build
Project name: inih
Project version: 58
C compiler for the host machine: cl (msvc 19.40.33816 "Microsoft (R) C/C++ Optimizing Compiler Version 19.40.33816 for x64")
C linker for the host machine: link link 14.40.33816.0
Host machine cpu family: x86_64
Host machine cpu: x86_64
Found pkg-config: YES (C:\ProgramData\chocolatey\bin\pkg-config.EXE) 0.28
..\src\meson.build:101: WARNING: add_languages is missing native:, assuming languages are wanted for both host and build.
C++ compiler for the host machine: cl (msvc 19.40.33816 "Microsoft (R) C/C++ Optimizing Compiler Version 19.40.33816 for x64")
C++ linker for the host machine: link link 14.40.33816.0
Build targets in project: 2

inih 58

  User defined options
    Native files: C:\conan_cache\b\inih555089f1c99b5\b\build\generators\conan_meson_native.ini
    prefix      : C:\

Found ninja-1.11.1 at C:\ProgramData\chocolatey\bin\ninja.EXE
memsharded commented 1 month ago

I am confused, it is not failing on my side, I get:

Found pkg-config: NO
..\src\meson.build:101: WARNING: add_languages is missing native:, assuming languages are wanted for both host and build.
C++ compiler for the host machine: cl (msvc 19.40.33813 "Microsoft (R) C/C++ Optimizing Compiler Version 19.40.33813 for x64")
C++ linker for the host machine: link link 14.40.33813.0
Build targets in project: 2

inih 58

  User defined options
    Native files: C:\Users\memsharded\.conan2\p\b\inih39c033d4fcb24\b\build\generators\conan_meson_native.ini
    prefix      : /

Found ninja-1.11.0 at "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.EXE"

inih/58: Meson build cmd: meson compile -C "C:\Users\memsharded\.conan2\p\b\inih39c033d4fcb24\b\build" -j8
inih/58: RUN: meson compile -C "C:\Users\memsharded\.conan2\p\b\inih39c033d4fcb24\b\build" -j8
conanvcvars.bat: Activating environment Visual Studio 17 - amd64 - winsdk_version=None - vcvars_ver=14.4
[vcvarsall.bat] Environment initialized for: 'x64'
INFO: autodetecting backend as ninja
INFO: calculating backend command to run: "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.EXE" -j 8
[2/5] Linking target inih-0.dll
   Creating library inih.lib and object inih.exp
[5/5] Linking target INIReader-0.dll
   Creating library INIReader.lib and object INIReader.exp

So it has prefix : /, but it doesn't fail

The difference about the pkgconfig found: NO is not an issue, if I add pkgconf/[*] to tool-requires, I get Found pkg-config: YES (C:/Users/Diego/.conan2/p/pkgcoe905804c6b50c/p/bin/pkgconf.exe) 2.2.0 and everything keeps working the same.

I keep investigating

shoeffner commented 1 month ago

We use pkgconfiglite, but I also doubt that's the issue. I am surprised it behaves differently, let me know if I can assist you in any other capacity.

memsharded commented 1 month ago

It might be possible that my Python installation understands / as a valid path.

Can you please try:

$ python
Python 3.10.2 (tags/v3.10.2:a58ebcc, Jan 17 2022, 14:12:15) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.listdir("/")
['$Recycle.Bin', 'appverifUI.dll', 'Config.Msi'...

Then please also report the output of conan version

shoeffner commented 1 month ago
Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.listdir("/")
['appverifUI.dll', 'Boot', 'bootmgr', 'BOOTNXT', 'BuildTools', 'ca-certificates.crt', ...

And conan version:

version: 2.8.1
conan_path: C:\python3\Scripts\conan
python
  version: 3.10.11
  sys_version: 3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)]
  sys_executable: C:\python3\python3.exe
  is_frozen: False
  architecture: AMD64
system
  version: 10.0.20348
  platform: Windows-10-10.0.20348-SP0
  system: Windows
  release: 10
  cpu: Intel64 Family 6 Model 85 Stepping 7, GenuineIntel
memsharded commented 1 month ago

Maybe the Meson installation? How did you installed? I installed it with pip install meson.

shoeffner commented 1 month ago

Indeed, that seems to be the issue!

We usually install meson with chocolatey (package references is https://github.com/mikeee/ChocoPackages/tree/master/automatic/meson), but I removed it and installed it via pip and the error is gone.

The chocolatey version seems to include a python313.dll, so I went ahead and installed Python 3.13, but the os.listdir output stays the same:

Python 3.13.0rc2 (tags/v3.13.0rc2:ec61006, Sep  6 2024, 22:13:49) [MSC v.1940 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.listdir("/")
['appverifUI.dll', 'Boot', 'bootmgr'...

However, I dug a little deeper and checked meson's code. Here is how they check for the abs path:

https://github.com/mesonbuild/meson/blob/c02e0b7b1e2499f3ae18d26e443e18043fff3046/mesonbuild/coredata.py#L360-L361

    def sanitize_prefix(self, prefix: str) -> str:
        prefix = os.path.expanduser(prefix)
        if not os.path.isabs(prefix):
            raise MesonException(f'prefix value {prefix!r} must be an absolute path')

And, as you might expect by now, Python 3.13 returns False for os.path.isabs("/"):

C:\>python3.10 -c "import os; print(os.path.isabs('/'))"
True
C:\>python3.13 -c "import os; print(os.path.isabs('/'))"
False
shoeffner commented 1 month ago

This is the PR which introduced this change: https://github.com/python/cpython/pull/113829

shoeffner commented 1 month ago

I guess I have to check if my PR even works with Python 3.13, if absolute directories get handled differently there (as Conan was still running 3.10 while meson used 3.13... fun times).

shoeffner commented 1 month ago
C:\>python3.10 -c "import os; print(os.path.abspath('/'))"
C:\
C:\>python3.13 -c "import os; print(os.path.abspath('/'))"
C:\

Seems to be fine though.

shoeffner commented 1 month ago

As a workaround, I will install meson with pip in our containers for now, but I'll happily work on that PR if you like me to.

Thanks a lot for digging into this, @memsharded!