mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.64k stars 1.64k forks source link

Directory path concatenation in the 'dir_name' argument of the subdir() function. #13874

Open rzharkov opened 2 weeks ago

rzharkov commented 2 weeks ago

On windows systems, passing 'dir_name' argument with intermediate subdirectories to the subdir() function, produces incorrect return values of current_build_dir() and current_source_dir() functions.

To Reproduce Create four subdirectories in a project directory:

./sd1
./sd1/sd11
./sd1/sd12
./sd1/sd13

Put into sd11, sd12, sd13 the same meson.build file with two function calls:

message(meson.current_source_dir())
message(meson.current_build_dir())

Execute these meson.build files with subdir() function from the root dir:

subdir('sd1/sd11')
subdir('sd1\sd12')
subdir('sd1' / 'sd13')

"meson setup" will produce output contains a mess of slashes and backslashes:

Message: C:\Home\Git\test\sd1/sd11
Message: C:\Home\Git\test\build\sd1/sd11
Message: C:\Home\Git\test\sd1\sd12
Message: C:\Home\Git\test\build\sd1\sd12
Message: C:\Home\Git\test\sd1/sd13
Message: C:\Home\Git\test\build\sd1/sd13

Here is the minimal test project: test.zip

This trouble was found in the "postgres" project where subdir('sd1/sd2') calls persist very often. subdir('src/include') for instance

Expected behavior Valid windows paths returned from current_build_dir() and current_source_dir() functions:

Message: C:\Home\Git\test\sd1\sd11
Message: C:\Home\Git\test\build\sd1\sd11
Message: C:\Home\Git\test\sd1\sd12
Message: C:\Home\Git\test\build\sd1\sd12
Message: C:\Home\Git\test\sd1\sd13
Message: C:\Home\Git\test\build\sd1\sd13

system parameters with the "meson setup" output The Meson build system Version: 1.4.0 Source dir: C:\Home\Git\test Build dir: C:\Home\Git\test\build Build type: native build Project name: tutorial Project version: undefined C compiler for the host machine: gcc (gcc 8.3.0 "gcc (x86_64-posix-seh, Built by strawberryperl.com project) 8.3.0") C linker for the host machine: gcc ld.bfd 2.32 Host machine cpu family: x86_64 Host machine cpu: x86_64 Message: C:\Home\Git\test\sd1/sd11 Message: C:\Home\Git\test\build\sd1/sd11 Message: C:\Home\Git\test\sd1\sd12 Message: C:\Home\Git\test\build\sd1\sd12 Message: C:\Home\Git\test\sd1/sd13 Message: C:\Home\Git\test\build\sd1/sd13 Build targets in project: 1

Found ninja-1.11.1.git.kitware.jobserver-1 at C:\Python3\Scripts\ninja.EXE

eli-schwartz commented 2 weeks ago

Expected behavior Valid windows paths returned from current_build_dir() and current_source_dir() functions:

But they are valid Windows paths! That is why subdir('sd1/sd11') isn't a fatal "no such directory" error.

The paths aren't consistently normalized, which is a different topic. But they are at least valid.

rzharkov commented 2 weeks ago

I agree, but 'cmd' called from meson.add_install_script() will fail with these paths.

sd1\sd11\meson.build:
message(meson.current_source_dir())
message(meson.current_build_dir())
meson.add_install_script(
    'cmd', '/c', 'copy', meson.build_root() / 'demo.exe', meson.current_build_dir()
  )
meson setup build --wipe && ninja -C build && ninja -C build install
...
The syntax of the command is incorrect.
Running custom install script 'C:\\Windows\\system32\\cmd.EXE /c copy C:/Home/Git/test/build/demo.exe C:\\Home\\Git\\test\\build\\sd1/sd11'
FAILED: install script 'C:\Windows\system32\cmd.EXE /c copy C:/Home/Git/test/build/demo.exe C:\Home\Git\test\build\sd1/sd11' failed with exit code 1.

I have no idea if it really needs to fix, but something is wrong with windows.

eli-schwartz commented 2 weeks ago

Using \ is problematic because the quoting rules are a bit nightmarish. Using / is problematic because certain older programs have bad option parsers that treat / anywhere in the command string as a flag prefix, e.g. Home/Git/test is treated as the flags /G and /t or perhaps /Git and /test. Basically you need to reformat your commands manually no matter what, and know in each case which programs you intend to pass it to.

meson's fs.copy() can at least in some cases fully replace the need for cmd /c copy.

rzharkov commented 2 weeks ago

Meanwhile I'm searching a replacement for fs.copyfile() on old versions of meson :)