On Windows, you can spawn a program using arbitrary Unicode characters in its command line. The arguments seen by the main() function in the argv[] array will have any characters outside the native code page replaced with '?'. A process can still see the original full command line, though, by using the GetCommandLineW() function. Unfortunately, the libtool wrapper does not preserve the original command line, and spawns the actual executable from the .libs directory with the out-of-codepage characters replaced by '?'. The wrapper should use GetcommandLineW() and pass the *original* arguments, not the sanitised ones from argv[]. Test case (which works when invoked directly but fails when invoked via libtool wrapper): #include <windows.h> #include <stdio.h> int main(int argc, char **argv) { HANDLE stdout_h = GetStdHandle(STD_OUTPUT_HANDLE); wchar_t *str; if (argc < 2) { printf("Need an argument\n"); return 1; } printf("argv[1] is '%s'\n", argv[1]); str = GetCommandLineW(); WriteConsoleW(stdout_h, str, wcslen(str), NULL, NULL); printf("\n"); return 0; } This is easily testable using mingw and wine.
David, thanks for the report. (In reply to David Woodhouse from comment #0) > On Windows, you can spawn a program using arbitrary Unicode characters in > its command line. > > The arguments seen by the main() function in the argv[] array will have any > characters outside the native code page replaced with '?'. > > A process can still see the original full command line, though, by using the > GetCommandLineW() function. > > Unfortunately, the libtool wrapper does not preserve the original command > line, and spawns the actual executable from the .libs directory with the > out-of-codepage characters replaced by '?'. > > The wrapper should use GetcommandLineW() and pass the *original* arguments, > not the sanitised ones from argv[]. This bugfix request should definitely go to upstream [1]. When talking about libtool wrapper on Windows, we are talking most likely about _development on_ Windows (not cross-platform development on linux for windows) - and that is somewhat out of scope Fedora. I'm hardly able to test it (I have no Windows box atm, sorry). Yep, wine ... > Test case (which works when invoked directly but fails when invoked via > libtool wrapper): ... but that ^^ does not seem to be truth, without libtool wrapper it does not work for me (though I am not sure what is behind): $ i686-w64-mingw32-gcc main.c $ wine ./a.exe "Žluťoučký" argv[1] is 'ÄluŁouŔkř' Z:\home\praiskup\rh\projects\tcsh\a.exe Žluťoučk Probably more self-standing example including 'Makefile.am' & 'configure.ac' together with step-by-step intro would be useful in case of such reports. [1] http://www.gnu.org/software/libtool/manual/html_node/Reporting-bugs.html Pavel
Created attachment 922455 [details] reproducer David, I'm curious enough - is that your issue: $ tar -xf windows-cross-compilation* $ cd windows-cross-compilation-1.1 $ ./configure --host=i686-w64-mingw32 $ make $ ./src/hello.exe "Příliš Žluťoučký Kůň" argv[1] is 'PrφliÜ Älutouck² Kun' Z:/tmp/windows-cross-compilation-1.1/src/.libs/hello.exe "Príliš Žlutoucký Kun" $ ./src/.libs/hello.exe "Příliš Žluťoučký Kůň" argv[1] is 'PrφliÜ Älutouck² Kun' Z:\tmp\windows-cross-compilation-1.1\src\.libs\hello.exe "Příliš Žluťoučký Kůň"
Yes. [dwoodhou@i7 windows-cross-compilation-1.1]$ src/hello.exe ♥ argv[1] is '?' Z:/home/dwmw2/Downloads/windows-cross-compilation-1.1/src/.libs/hello.exe ? [dwoodhou@i7 windows-cross-compilation-1.1]$ src/.libs/hello.exe ♥ argv[1] is '?' Z:\home\dwmw2\Downloads\windows-cross-compilation-1.1\src\.libs\hello.exe ♥ [dwoodhou@i7 windows-cross-compilation-1.1]$
Thanks for taking the time to produce the test case, btw. As for cross-building for Windows being out of scope for Fedora, the MinGW SIG may not entirely agree with you there :) I've added their list to Cc.
(In reply to David Woodhouse from comment #4) > As for cross-building for Windows being out of scope for Fedora I'm not familiar with this use-case, I need to look at it more carefully TBH. But I thought that the binary libtool wrapper is not installed -- so it would be low prio issue as we mail live without that. But that may have been pretty likely untrue?
sudo yum install mingw32-gcc mingw32-configure make wine program.exe .. works, on Fedora, for many libraries and programs.
You're correct that we don't *install* the binary libtool wrapper. Whether building natively, or building with MinGW, the wrapper is only used for running the program locally inside the build tree. When developing software, this is useful — you make a change, you build and you run it from the build tree to test it. The MinGW support on Fedora is extremely useful — I can have build trees for Linux and for Windows side by side, and test my changes in both environments (mostly using Wine, and then occasionally actually testing on real Windows too). But when I was adding full UTF16 command line handling for Windows, the Fedora MinGW setup failed me because of this bug. I *had* to test every little change on real Windows, which is a PITA. At least until I realised it wasn't a wine bug, and I could work around it :)
Ok, I'm little bit closer to the problem, probably. I'm not familiar with windows, so I'm not sure. Looking at the GetcommandLineW from comment #1 is not a way to go, I would say, because it does not preserve arguments with spaces like './test.exe "arg a" arg_b' to be parsed later. What we would need is to switch from 'main' to 'wmain' and use -municode. Dunno how portable that is, probably we could use it when we are allowed to (hidden behind some #ifdef/configure checks). Argv from wmain may then be passed to _wspawnv instead of _spawnv (as is done in libtool wrapper now). Any ideas?
(In reply to Pavel Raiskup from comment #8) > Ok, I'm little bit closer to the problem, probably. I'm not familiar with > windows, so I'm not sure. Looking at the GetcommandLineW from comment #1 > is not a way to go, I would say, because it does not preserve arguments with > spaces like './test.exe "arg a" arg_b' to be parsed later. Que? #include <windows.h> #include <stdio.h> int main(int argc, char **argv) { HANDLE stdout_h = GetStdHandle(STD_OUTPUT_HANDLE); wchar_t **argv_w; wchar_t *str; if (argc < 2) { printf("Need an argument\n"); return 1; } printf("argc %d, argv[1] is '%s'\n", argc, argv[1]); str = GetCommandLineW(); argv_w = CommandLineToArgvW(str, &argc); printf("argc_w %d, argv_w[1] is '", argc); WriteConsoleW(stdout_h, argv_w[1], wcslen(argv_w[1]), NULL, NULL); printf("'\n"); return 0; } [dwoodhou@i7 ~]$ $ wine foo.exe "foo♥ bar" argc 2, argv[1] is 'foo? bar' argc_w 2, argv_w[1] is 'foo♥ bar'
(In reply to David Woodhouse from comment #9) > (In reply to Pavel Raiskup from comment #8) > > Looking at the GetcommandLineW from comment #1 is not a way to go, I would > > say, because it does not preserve arguments with spaces like './test.exe > > "arg a" arg_b' to be parsed later. > > Que? Argh, I missed the LPWSTR hides something more then wchar_t. Thanks!
Raised upstream bug, better to discuss/fix there: http://news.gmane.org/gmane.comp.gnu.libtool.bugs
Better link: http://article.gmane.org/gmane.comp.gnu.libtool.bugs/8300
This message is a reminder that Fedora 20 is nearing its end of life. Approximately 4 (four) weeks from now Fedora will stop maintaining and issuing updates for Fedora 20. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as EOL if it remains open with a Fedora 'version' of '20'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, simply change the 'version' to a later Fedora version. Thank you for reporting this issue and we are sorry that we were not able to fix it before Fedora 20 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora, you are encouraged change the 'version' to a later Fedora version prior this bug is closed as described in the policy above. Although we aim to fix as many bugs as possible during every release's lifetime, sometimes those efforts are overtaken by events. Often a more recent Fedora release includes newer upstream software that fixes bugs or makes them obsolete.
This message is a reminder that Fedora 21 is nearing its end of life. Approximately 4 (four) weeks from now Fedora will stop maintaining and issuing updates for Fedora 21. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as EOL if it remains open with a Fedora 'version' of '21'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, simply change the 'version' to a later Fedora version. Thank you for reporting this issue and we are sorry that we were not able to fix it before Fedora 21 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora, you are encouraged change the 'version' to a later Fedora version prior this bug is closed as described in the policy above. Although we aim to fix as many bugs as possible during every release's lifetime, sometimes those efforts are overtaken by events. Often a more recent Fedora release includes newer upstream software that fixes bugs or makes them obsolete.
This package has changed maintainer in Fedora. Reassigning to the new maintainer of this component.
According to the low priority of this request and as it did not bother any user for years, I am closing this tracker. If you think this issue should be handled and investigated, feel free to reopen it.