Bug 74559 - Pathnames mangled under windows
Summary: Pathnames mangled under windows
Status: RESOLVED NOTABUG
Alias: None
Product: fontconfig
Classification: Unclassified
Component: library (show other bugs)
Version: unspecified
Hardware: x86 (IA32) Windows (All)
: medium normal
Assignee: fontconfig-bugs
QA Contact: Behdad Esfahbod
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-02-05 11:30 UTC by Dirk
Modified: 2014-02-20 14:00 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments
Default to "Windows font Directory" if no config can be found (1.81 KB, patch)
2014-02-15 15:36 UTC, Dirk
Details | Splinter Review
Default to "Windows font Directory" if no config can be found - patch 2 (1.15 KB, patch)
2014-02-15 15:37 UTC, Dirk
Details | Splinter Review

Description Dirk 2014-02-05 11:30:47 UTC
I have compiled fontconfig as a static library (not a dll) on Windows (Windows 7) using Mingw64 under MSYS. 

The issue I am facing is that all the path names inside of fontconfig are being mangled from the provided /dir/subdir/fonts to c:\msys\dir\subdir\fonts. For example in the test folder of the source tree I see fonts.conf.in
<fontconfig>
<dir>@FONTDIR@</dir>
<cachedir>@CACHEDIR@</cachedir>
</fontconfig>
which translates (under MSYS) to the correct answer of 
<fontconfig>
<dir>/home/dirk/mybuild/test/fonts</dir>
<cachedir>/home/dirk/mybuild/test/cache.dir</cachedir>
</fontconfig>

However if I now run fc-list, fc-cat or whatever either in a Windows command prompt, or in the MSYS shell I get no output. If I change the <dir> tag to 
<dir>c:\msys\home\dirk\mybuild\test\fonts</dir>, I get output when running on windows command prompt. No matter what combination of stuff I put in fonts.conf execution in the MSYS shell fails. Note that the environment variable FONTCONFIG_FILE is being correctly treated as a unix path under MSYS, and a windows path under windows command prompt (i.e. I don't get "Fontconfig error: Cannot load default config file" when these are set appropriately). However from there on the path mangeling takes effect on the paths and files defined in the fonts.conf. Note, I don't know if the package is not reading the fonts.conf under MSYS (after checking for its existence), or if the file is being parsed and the file / path names are getting messed up after they are read.

On inspection I see that there is a bunch of code in fontconfig (copied from fccfg.c) that does:
#ifdef _WIN32
	{
		char *p;
		if(!GetModuleFileName(NULL, (LPCH) fontconfig_path, sizeof(fontconfig_path))) ........
#endif

This test (_WIN32) does not take account of whether the library is compiled as a dll (shared) or not. I have not checked the windows API to see if it returns a path when invoked from a static library, but documentation indicates that it will.
The test also does not care that the execution environment is unix like (MSYS, CygWin) or Windows. I haven't looked at this under CygWin and cannot comment if the same issue applies, but I assume it will. 

In all events a path returned by the windows GetModuleFileName API is not going to work with unix like paths used in standard c. With a test like this at compile time, perhaps a better test would be 
#if defined (_WIN32) && defined (_MSCVER)
on the assumption that if microsofts compiler is involved then the target is vanilla windows? Or otherwise a test for _POSIX to see if standard path resolution can be done?
Comment 1 Akira TAGOH 2014-02-06 01:57:25 UTC
I think configure may not detects win32 support properly. I guess you don't have OS_WIN32=yes as a result of configure. otherwise FC_DEFAULT_FONTS should be WINDOWSFONTDIR and cachedir should be LOCAL_APPDATA_FONTCONFIG_CACHE by default, instead of Unix-like path. how did you run configure script? you need to run it with the appropriate --host option to get it working with mingw.
Comment 2 Dirk 2014-02-06 04:58:44 UTC
Configure command:
/home/dirk/mybuild>../fontconfig-2.11.0/configure --prefix=/opt/mingwExtra --enable-static --enable-shared=no

Environment set at configure time:
# winSet - set compile options for windows target
export CC=gcc
export CXX=g++
export AR=ar
export NM=nm
export PATH="/opt/winw32/bin:/opt/mingwExtra/bin:/bin:/c/Program Files/MiKTeX/miktex/bin:/c/Program Files/CMake/bin"
export build_alias="i686-w64-mingw32"
export host_alias="i686-w64-mingw32"
export CPPFLAGS="-I/opt/mingwExtra/include"
export CMAKE_INCLUDE_PATH="/opt/mingwExtra/include"
export CMAKE_LIBRARY_PATH="/opt/mingwExtra/lib"
export LDFLAGS="-L/opt/mingwExtra/lib"
export PKG_CONFIG_LIBDIR="/opt/mingwExtra/lib/pkgconfig"


config.log: (whether this is true or false I dunno :) )
OS_WIN32_FALSE='#'
OS_WIN32_TRUE=''

config.h:
#define FC_DEFAULT_FONTS "WINDOWSFONTDIR"


So I guess it is picking up I am on win32, but understand that I want the paths to be unix like. I am compiling and executing under MSYS not under native windows.
Comment 3 Akira TAGOH 2014-02-06 05:52:36 UTC
If you want to build it on non-native windows platform, you shouldn't explicitly set --build and $build_alias. it is to specify the build host you are configuring on. only --host or $host_alias works for cross-compiling. see the document for autotools.

Anyway, I don't see any issues at this moment since you have `#define FC_DEFAULT_FONTS "WINDOWSFONTDIR"' line in config.h, that should works and won't generate something like you initially reported.

Please reopen and explain more if you still see any issues.

Thanks,
Comment 4 Dirk 2014-02-06 07:28:05 UTC
In this scenario, I am not cross compiling. I am explicitly building on mingw for mingw. This is distinct to building with a microsoft compiler on windows for windows. With a different bunch of environment variables in this same setup I also cross compile from mingw targeting powerpc-ibm-aix5.1.0.0. I guess that specifying the build value is kindof redundant as autoconf should guess it correctly, however I need to set the host value so that it is the correct answer for this compile stream as opposed to the cross compile setting. I guess I could as well just unset the host-alias value when targeting a local build - but I figured better to be explicit rather than leave things to chance.

Having said all that I still am unable to run the simple "basic check" that is inside of test/run-test.sh under msys. With a lot of fiddling inside of the fonts.conf, and setting the FONTCONFIG_FILE to a C:\msys\home\dirk\myBuild\test this does work from a windows command prompt. But the point is I am building the fontconfig library under msys using a standard c library, and intend to link to it from programs in msys, so the library build is effectivly broken as (in my opinion) a result of path mangeling. What I am seeing is that any application trying to use fontconfig on windows would have to also jump through all the path translation stuff that is built into fontconfig to specify which config file to use, and where the cache is and etc.

Note that in my experience, any c library, be it gnu-linux, windows or whatever is happy with paths expressed as /adir/asubdir, so all of the string replace of '/' to '\\' when _WIN32 is defined is not necessary, and in this instance is breaking the functionality of the library under msys. Even with a native microsoft compiler, standard c functions like stat(), mkdir() and etc. will use paths expresed as /x/y/x and do not need the translation to c:\x\y\z. It is only when one starts to use actual windows api's like GetModuleFileName() that the world becomes complicated with microsoft "\" notation. In this case I am using gcc to compile, so the implication is that I have a standard c library that is mostly POISIX/GNU/C99 compliant.

Has anyone had success with compiling and using fontconfig on cygwin? I think that cygwin environment does its own path mangeling, so I dunno how that will co-exist with fontconfigs efforts.
Comment 5 Akira TAGOH 2014-02-06 07:46:22 UTC
(In reply to comment #4)
> In this scenario, I am not cross compiling. I am explicitly building on
> mingw for mingw. This is distinct to building with a microsoft compiler on
> windows for windows. With a different bunch of environment variables in this
> same setup I also cross compile from mingw targeting powerpc-ibm-aix5.1.0.0.
> I guess that specifying the build value is kindof redundant as autoconf
> should guess it correctly, however I need to set the host value so that it
> is the correct answer for this compile stream as opposed to the cross
> compile setting. I guess I could as well just unset the host-alias value
> when targeting a local build - but I figured better to be explicit rather
> than leave things to chance.

I see.

> Having said all that I still am unable to run the simple "basic check" that
> is inside of test/run-test.sh under msys. With a lot of fiddling inside of
> the fonts.conf, and setting the FONTCONFIG_FILE to a
> C:\msys\home\dirk\myBuild\test this does work from a windows command prompt.
> But the point is I am building the fontconfig library under msys using a
> standard c library, and intend to link to it from programs in msys, so the
> library build is effectivly broken as (in my opinion) a result of path
> mangeling. What I am seeing is that any application trying to use fontconfig
> on windows would have to also jump through all the path translation stuff
> that is built into fontconfig to specify which config file to use, and where
> the cache is and etc.

Ah, okay. got it. well, I don't think test/run-test.sh does take care of win32 platform and apparently not. and no one complained about it ever.
So that could be indeed improved.

> Note that in my experience, any c library, be it gnu-linux, windows or
> whatever is happy with paths expressed as /adir/asubdir, so all of the
> string replace of '/' to '\\' when _WIN32 is defined is not necessary, and
> in this instance is breaking the functionality of the library under msys.
> Even with a native microsoft compiler, standard c functions like stat(),
> mkdir() and etc. will use paths expresed as /x/y/x and do not need the
> translation to c:\x\y\z. It is only when one starts to use actual windows
> api's like GetModuleFileName() that the world becomes complicated with
> microsoft "\" notation. In this case I am using gcc to compile, so the
> implication is that I have a standard c library that is mostly
> POISIX/GNU/C99 compliant.

AFAIK win32 support has been improved with contributions from win32 developers. if you aren't comfortable with it on msys, any improvements are always welcome.
please make sure in advance you don't make any regressions with it.

> Has anyone had success with compiling and using fontconfig on cygwin? I
> think that cygwin environment does its own path mangeling, so I dunno how
> that will co-exist with fontconfigs efforts.

I see 2.10.93 in their builds at least and I don't think we've drastically changed for win32 since then.
Comment 6 Dirk 2014-02-06 08:46:03 UTC
I think that such changes would be a BIG patch! Will have a closer look over the next couple of days.

Is this libarary supposed to compile with a microsoft compiler (borland / watcom / etc.)? I don't have such animals to hand, and dunno that that I want to go the effort of installing / learning such a build environment, so testing for that scenario would be difficult for me. Espescially if the library is linked (dll or static) to an application built using those tools.

I guess a differnt way to ask this question is (to your knowledge) which native win32 applications are using fontconfig?
Comment 7 Akira TAGOH 2014-02-06 08:57:37 UTC
(In reply to comment #6)
> Is this libarary supposed to compile with a microsoft compiler (borland /
> watcom / etc.)? I don't have such animals to hand, and dunno that that I
> want to go the effort of installing / learning such a build environment, so
> testing for that scenario would be difficult for me. Espescially if the
> library is linked (dll or static) to an application built using those tools.

What I've heard ATM is someone is trying to build with MSVC, cygwin and mingw.

> I guess a differnt way to ask this question is (to your knowledge) which
> native win32 applications are using fontconfig?

any free software and GTK+ applications being ported to win32. e.g. gimp, inkscape, ffmpeg, mplayer etc.
Comment 8 Dirk 2014-02-15 15:35:26 UTC
OK, after a lot of investigation I see that the issue comes about because I have compiled the fontconfig library as static. The result of this is that all of the tricks used in fontconfig to determin the location of the default fonts.conf file are failing. Why; because DllMain in fcconfig.c will never execute with a staticly bound object.

I make an assumption here that you guys will be in a better possition to answer: Namely that under windows a default fonts.conf is not required! Unless one chooses to explicitly override the fonts.conf with an application specific directory (via an environment variable), the default answer is going to be Windows Font Directory - with no fonts.conf required.

Given this assumption, I submit some patches that should not impact in any way existing functionality, but adds a "catch all" fonts config of Windows Fonts Directory in the event that the existing code does not a good answer.

Comments / evaluation / and etc. are welcome.
Comment 9 Dirk 2014-02-15 15:36:38 UTC
Created attachment 94124 [details] [review]
Default to "Windows font Directory" if no config can be found
Comment 10 Dirk 2014-02-15 15:37:16 UTC
Created attachment 94125 [details] [review]
Default to "Windows font Directory" if no config can be found - patch 2
Comment 11 Akira TAGOH 2014-02-17 03:13:27 UTC
(In reply to comment #8)
> I make an assumption here that you guys will be in a better possition to
> answer: Namely that under windows a default fonts.conf is not required!
> Unless one chooses to explicitly override the fonts.conf with an application
> specific directory (via an environment variable), the default answer is
> going to be Windows Font Directory - with no fonts.conf required.

Well, that assumption sounds a bit wrong. the issue isn't only to determine the fonts directory. you need to set the cache directory too and AFAIK the main customers for fontconfig usually bundles the library and fonts.conf. which means they have own certain directories as well.
plus, you'll miss the way of the customization in this manner. I got the point but I don't think that is worth merging into the master.

We may need to do things in DllMain() for static linking like:

void
win32init(void) __attribute__((constructor))
{
[...]
}

in gcc extension as well as something in the way of MSVC and so on.
Comment 12 Dirk 2014-02-17 06:58:07 UTC
Yeah, I get your point also (with respect to stuff in fonts config other than the fonts and cache directory) Note that the patch does achieve a cache directory.

The (unpatched) code aleady makes effort to get the executable directory in the event that dllMain is not invoked and then use that as a basis for fonts.conf aquisition. Problem is that this executable will whatever the "run" directory is at invokation i.e. equivalent to pwd.

In the event of a static link, I dont know of a way to get back to the directory of the statically linked library from the executable? For example if the library sits in /usr/local/lib, and my statically linked executable sits in /opt/somestuff/bin, the closest I can come to finding a runtime directory will be /opt/somestuff/bin with (to my limited knowledege) no way of getting back to /usr/local/lib.
Comment 13 Akira TAGOH 2014-02-19 09:45:36 UTC
Thus we are determining the relevant directories at the build time. no exception for static linking even. applications which needs specific places for fonts and config would usually bundles their own builds of libraries and relevant files rather than using one where installed on the system.
Comment 14 Dirk 2014-02-20 14:00:47 UTC
OK - I guess I can take the build time approach for my own purposes as well. 

Thanks for all your comments!


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.