@LRN
Copy link

LRN commented Apr 24, 2019

There are multiple problems with building appstream on Windows with MinGW-w64:

  • Includes <sys/utsname.h> (missing on Windows) unconditionally.
    • Should use ccompiler.has_header() to detect it at configure-time, then conf.set('HAVE_SYS_UTSNAME', result-of-the-check)
  • Uses <fnmatch.h> (missing on Windows) for `fnmatch().
    • Should use <glib/gpattern.h> and g_pattern_match_simple(), or something along these lines.
  • as_get_current_arch() uses utsname (see above) and needs a Windows-specific implementation.
    • A simple GetSystemInfo() call should do the trick (though be mindful of PROCESSOR_ARCHITECTURE_* constants, some of them are not in MinGW-w64 headers yet).
  • directory_is_empty() uses opendir() & friends. Doesn't work with utf-8 filenames, and only works on Windows because MinGW has an implementation (so no MSVC compatibility).
    • Replace with g_dir_open() & friends.
  • as_utils_is_root() uses unportable means of checking for administrative privileges (checks UID).
    • There's some code (see Solution #3) that you can re-use, although i would suggest getting rid of __try() & friends, as these don't work with MinGW.
  • as-distro-extras.c uses symlink() (absent on Windows)
    • It's easy to approximate with CreateSymbolicLinkW() (Vista-or-later required - add_global_arguments ('-D_WIN32_WINNT=0x600', language : 'c')), with a bit of extra code for utf-8->utf-16 conversion (glib has that), though be sure to add SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE flag. Note that you also need a special flag to make a directory symlink, so this function works either on files only or on directories only, depending on the flags. Appstream seems to use symlink() only for files, and when it won't, the caller would surely know what is being linked, so the appropriate context information can be passed down.
  • ascli-actions-mdata.c uses uint instead of gint (causes a warning)
  • appstream-cli.c uses isatty(fileno (stdout)) - very problematic on Windows.
    • Use g_log_writer_supports_color (fileno (stdout)) instead.
  • Meson builddefs add unconditional 'gio-unix-2.0' dependency
    • Make it conditional on host_machine.system() != 'windows'. No need for gio-win32-2.0 or anything in the else branch, AFAICS.
  • Meson builddefs have bizarre include_directories(['/usr/include']).
    • Just remove that.
  • as_distro_details_get_str() crashes because it can call g_key_file_get_string() with NULL key and id.
    • Check for priv->keyf != NULL && priv->id != NULL, return NULL if the check fails. Same goes for other places where priv->id or priv->keyf are used - add NULL checks.