The Cflags of this package include a -I/mingw64/include which is not translated by pkgconf to a Windows path leading to further errors later on (in this case in ghc-pkg).
Note that Windows APIs usually normalize forward slashes in pathnames into backward slashes (see https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#canonicalize-separators or the c-runtime doc for instance). This is why you can (and should) use forward slashes when you #include a file in a C or C++ program, and this is also why both slashes are formally disallowed in Windows file names. Doing this at the API level is infinitely more sensible than having pkgconf or ghc-pkg assume one or the other in strings that may or may not be pathnames.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
So there is indeed a difference in how pkgconf treats these paths, and the one considered canonical (or "system include path") is the C:/ one.
Also, the documentation for MinGW already discusses this problem (see this) from which I can quote the following:
The only solution here is to avoid mixing Unix/Cygwin and native tools outside of makepkg (preferred) or convert them when they get passed between the different programs.
Which would support my point because pkgconf will offer system paths as C:/-style paths.
Now on the other hand, I understand your point about being the Windows API the one that normalizes the path. I think however that is not correct in this case, as Powershell does not understand /mingw64 paths:
It is true that the documentation of MinGW states that:
When calling native executables from the context of Cygwin then all the arguments that look like Unix paths will get auto converted to Windows.
However it doesn't specify whether paths contained in data that will be offered by executables (as it is the case for this pkgconf issue, the path is data in the .pc file and is returned in the output) should be translated, neither it says they should not be translated. Same for how autoconf should offer the results.
I see two possible outcomes out of this:
either this package (and some others I reported the same problem) change to not produce resulting /mingw64 paths in their .pc files. I understand this might require moving this issue upstream into autoconf or similar.
either GHC (more particularly now ghc-pkg) should, if presented with a Unix path, call cygpath to find out the canonical Windows path always.
I think the first solution is the right thing to do and the second solution just a stop-gap measure until some other package or some other compiler or tool falls into the same problem.
I would like to hear your opinion on this and whether you see any other solutions.
Last edit: Javier Sagredo 2023-11-27
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
1) I just checked that pkgconf records the list of system include directories that were used during its compilation and uses this as the default value of PKG_CONFIG_SYSTEM_INCLUDE_PATH. This explains your observation about pkgconf treating certain paths differently. Also I believe that ddjvuapi.pc contains /mingw64/include because this is where libjpeg lives (there are mingw64 packages, msys packages, mingw within msys packages, etc.)
2) The definition of "relative path" in the ghc-conf error message ignores a lot of the complexities of Windows which has both a current drive and current directories for each drive. If the meaning is to be "non-absolute", then what about UNC pathnames of the form \partition\xx\yyy? What about the passthru pathnames starting with \\?\ which are entirely interpreted by the file system code, possibily differently by different file systems. Not even speaking of device pathnames starting with \\.\ and about the cases where the API understands a NT pathname instead of a WIN32 pathname (yes they are different). Are all these cases handled correctly?
3) The Microsoft shells do not accept /, but the Microsoft APIs have all moved in that direction long ago. See for instance the doc of the fundamental Win32 CreateFile call: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea. I believe that the Microsoft shells resist this trend because a lot of dos utilities accept options starting with a slash using code that assumes that anything starting with a forward slash is an option. So the API people like slashes but the shell people do not.
In my view, the alternatives are:
change a dozen project that were happily letting Windows sort its pathname mess, asking them instead to write code that produces pathnames that resemble what ghc-conf thinks Windows pathnames mean.
remove this ill advised and incomplete test from ghc-conf.exe. I suggest to replace it by a much simpler test: skip a possible drive specification (a letter followed by a colon) and check that what remains starts with a forward or backward slash. That would flag the most obvious problems without forbidding things that are too cumbersome to fully address.
This seems pretty clear cut to me.
Last edit: Leon Bottou 2023-11-27
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The definition of "relative path" in the ghc-conf error message ignores a lot of the complexities of Windows which has both a current drive and current directories for each drive. If the meaning is to be "non-absolute", then what about UNC pathnames of the form \partition\xx\yyy
No, it does not ignore any complexities. UNC pathnames are detected as absolute and your example is wrong. They start with two slashes: "\\partition\xx\yyy".
What about the passthru pathnames starting with \?\ which are entirely interpreted by the file system code, possibily differently by different file systems. Not even speaking of device pathnames starting with \.\ and about the cases where the API understands a NT pathname instead of a WIN32 pathname (yes they are different). Are all these cases handled correctly?
Yes they are. Why are you asking?
The Microsoft shells do not accept /, but the Microsoft APIs have all moved in that direction long ago.
We're aware and all this is already handled correctly.
"/mingw64/include" is not an absolute pathname under any circumstance on windows. This path is in fact a relative path in relation to the current device root. It is the same as "\mingw\include". It is not a UNC pathname. It is not absolute.
Please inform yourself. Relative paths in pkgconfig files are broken and cannot work.
Last edit: hasufell 2023-12-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am not sure I understand the nature of the bug.
The contents of ddjvuapi.pc is not hardcoded but constructed from https://sourceforge.net/p/djvu/djvulibre-git/ci/master/tree/libdjvu/ddjvuapi.pc.in using the information gathered by the autoconf process. All this uses forward slashes as path separator, which works fine with MinGW.
Note that Windows APIs usually normalize forward slashes in pathnames into backward slashes (see https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#canonicalize-separators or the c-runtime doc for instance). This is why you can (and should) use forward slashes when you #include a file in a C or C++ program, and this is also why both slashes are formally disallowed in Windows file names. Doing this at the API level is infinitely more sensible than having pkgconf or ghc-pkg assume one or the other in strings that may or may not be pathnames.
I understand your point, and I'm open to discuss this (perhaps it is GHC the one that has to change how it works!).
On the one hand, we get this output from the current
.pcfile:This is because of the way this pkgconf file is constructed, where
-I/mingw64/includeis hard-coded in the resulting file:However, if I change that file to provide (hard-coded)
-IC:/msys64/mingw64/includethen the following happens:So there is indeed a difference in how pkgconf treats these paths, and the one considered canonical (or "system include path") is the
C:/one.Also, the documentation for MinGW already discusses this problem (see this) from which I can quote the following:
Which would support my point because
pkgconfwill offer system paths asC:/-style paths.Now on the other hand, I understand your point about being the Windows API the one that normalizes the path. I think however that is not correct in this case, as Powershell does not understand
/mingw64paths:In any case this could be solved by a call to
cygpathas mentioned in the linked docs:It is true that the documentation of MinGW states that:
However it doesn't specify whether paths contained in data that will be offered by executables (as it is the case for this pkgconf issue, the path is data in the
.pcfile and is returned in the output) should be translated, neither it says they should not be translated. Same for howautoconfshould offer the results.I see two possible outcomes out of this:
/mingw64paths in their.pcfiles. I understand this might require moving this issue upstream into autoconf or similar.cygpathto find out the canonical Windows path always.I think the first solution is the right thing to do and the second solution just a stop-gap measure until some other package or some other compiler or tool falls into the same problem.
I would like to hear your opinion on this and whether you see any other solutions.
Last edit: Javier Sagredo 2023-11-27
1) I just checked that pkgconf records the list of system include directories that were used during its compilation and uses this as the default value of PKG_CONFIG_SYSTEM_INCLUDE_PATH. This explains your observation about pkgconf treating certain paths differently. Also I believe that ddjvuapi.pc contains /mingw64/include because this is where libjpeg lives (there are mingw64 packages, msys packages, mingw within msys packages, etc.)
2) The definition of "relative path" in the ghc-conf error message ignores a lot of the complexities of Windows which has both a current drive and current directories for each drive. If the meaning is to be "non-absolute", then what about UNC pathnames of the form \partition\xx\yyy? What about the passthru pathnames starting with \\?\ which are entirely interpreted by the file system code, possibily differently by different file systems. Not even speaking of device pathnames starting with \\.\ and about the cases where the API understands a NT pathname instead of a WIN32 pathname (yes they are different). Are all these cases handled correctly?
3) The Microsoft shells do not accept /, but the Microsoft APIs have all moved in that direction long ago. See for instance the doc of the fundamental Win32 CreateFile call: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea. I believe that the Microsoft shells resist this trend because a lot of dos utilities accept options starting with a slash using code that assumes that anything starting with a forward slash is an option. So the API people like slashes but the shell people do not.
In my view, the alternatives are:
This seems pretty clear cut to me.
Last edit: Leon Bottou 2023-11-27
No, it does not ignore any complexities. UNC pathnames are detected as absolute and your example is wrong. They start with two slashes: "\\partition\xx\yyy".
Yes they are. Why are you asking?
We're aware and all this is already handled correctly.
"/mingw64/include" is not an absolute pathname under any circumstance on windows. This path is in fact a relative path in relation to the current device root. It is the same as "\mingw\include". It is not a UNC pathname. It is not absolute.
Please inform yourself. Relative paths in pkgconfig files are broken and cannot work.
Last edit: hasufell 2023-12-02