msys2 / msys2/msys2-runtime

Unexpected/Incorrect Path Conversion when Exporting Environment Variables

Open
#152 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
240
Forks
60
Avg merge
2d 3h
Merged PRs (30d)
1

Description

I recently updated my msys and noticed that some Makefile recipes started failing. Basically, whenever more than one path-like string is exported, a weird conversion kicks in that tries to split each single path as if it were a list of paths and then replaces the first forward slash /.

As far as I understand, make exports variables through the environment for subsequent invocations of tools using the export command, so this isn't the usual path mangling when using command-line arguments or at least I assume that make does not invoke a second executable and passes the exported data via command-line arguments to achieve this.

I reduced this down to the following minimal example:

ex
│   Makefile
└───dir
        Makefile

The Makefile contents are simple:

##########################################################################
# Makefile

.PHONY: foo
foo: export SINGLE += $(abspath file1)
foo: export DOUBLE += $(abspath file2) $(abspath file3)
foo:
	@echo "SHELL = $(SHELL)"
	@echo "SINGLE = $(SINGLE)"
	@echo "DOUBLE = $(DOUBLE)"
	+@cd dir && $(MAKE) bar && cd ..

##########################################################################
# dir/Makefile

.PHONY: bar
bar:
	@echo "SHELL = $(SHELL)"
	@echo "SINGLE = $(SINGLE)"
	@echo "DOUBLE = $(DOUBLE)"

The output with msys-2.0.dll version 3004.3.0.0 used to be:

$ mingw32-make foo
SHELL = C:/msys2/usr/bin/sh.exe
SINGLE = C:/tmp/ex/file1
DOUBLE = C:/tmp/ex/file2 C:/tmp/ex/file3
mingw32-make[1]: Entering directory 'C:/tmp/ex/dir'
SHELL = C:/msys2/usr/bin/sh.exe
SINGLE = C:/tmp/ex/file1
DOUBLE = C:/tmp/ex/file2 C:/tmp/ex/file3
mingw32-make[1]: Leaving directory 'C:/tmp/ex/dir'

However with msys-2.0.dll version 3004.6.0.0 the output is:

$ mingw32-make foo
SHELL = C:/msys2/usr/bin/sh.exe
SINGLE = C:/tmp/ex/file1
DOUBLE = C:/tmp/ex/file2 C:/tmp/ex/file3
mingw32-make[1]: Entering directory 'C:/tmp/ex/dir'
SHELL = C:/msys2/usr/bin/sh.exe
SINGLE = C:/tmp/ex/file1
DOUBLE = C;C:\msys2\ex\file2 C;C:\msys2\ex\file3        # <-- error on this line
mingw32-make[1]: Leaving directory 'C:/tmp/ex/dir'

Basically, the each path is treated as if the first colon : was actually a separator within a list of paths, then the first forward slash / is replaced by the msys2 base directory and then the paths are concatenated again using the windows separator for lists of paths, semicolon ;.

I strongly suspect this is related to #150, because as one can see, it does not happen with just a single path.
However, curiously this error does not occur when the exported list itself starts with a space, so using foo: export DOUBLE := $(DOUBLE) $(abspath file2) $(abspath file3) (DOUBLE is initially empty) does not trigger this behavior. This leads me to believe this might be a slightly different case.

I also noticed that the behavior does not occur when using SHELL = cmd, so it's definitely the invocation of sh.exe in line 3 of the foo recipe that's causing the issue. Unfortunately, MSYS2_ARG_CONV_EXCL does not have any effect on this.

I apologize for the somewhat lengthy issue ;)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the minimal Makefile example with the two reported msys-2.0.dll versions and compare the nested mingw32-make invocation through sh.exe. The payload names no implementation files or tests; done means exported values containing multiple paths remain unchanged across the nested invocation, with coverage for the reported case.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, shell
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.