Maker of open-source software and hardware.

Attempting to get libmtp compiled on Windows

A couple of days ago I mentioned that I'm attempting to compile libmtp under MSYS2/MINGW64. Steps so far:

Some useful MSYS2-specific things:

Now, after all of this I still got the following error:

unicode.c: In function 'utf16_to_utf8':
unicode.c:91:23: error: 'PTPParams' {aka 'struct _PTPParams'} has no member named 'cd_ucs2_to_locale'
   91 |   nconv = iconv(params->cd_ucs2_to_locale, &stringp, &convlen, &locp, &convmax);
      |                       ^~
unicode.c: In function 'utf8_to_utf16':
unicode.c:126:23: error: 'PTPParams' {aka 'struct _PTPParams'} has no member named 'cd_locale_to_ucs2'
  126 |   nconv = iconv(params->cd_locale_to_ucs2, &stringp, &convlen, &unip, &convmax);

Turns out, it's a known issue. Based on a potential fix linked to in that GitHub issue, I was able to write a fix for a different file:

diff --git a/src/unicode.c b/src/unicode.c
index 2adc94e..b14274b 100644
--- a/src/unicode.c
+++ b/src/unicode.c
@@ -87,12 +87,14 @@ char *utf16_to_utf8(LIBMTP_mtpdevice_t *device, const uint16_t *unicstr)
   size_t convmax = STRING_BUFFER_LENGTH*3;

   loclstr[0]='\0';
+  #if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H)
   /* Do the conversion.  */
   nconv = iconv(params->cd_ucs2_to_locale, &stringp, &convlen, &locp, &convmax);
   if (nconv == (size_t) -1) {
     // Return partial string anyway.
     *locp = '\0';
   }
+  #endif
   loclstr[STRING_BUFFER_LENGTH*3] = '\0';
   // Strip off any BOM, it's totally useless...
   if ((uint8_t) loclstr[0] == 0xEFU && (uint8_t) loclstr[1] == 0xBBU && (uint8_t) loclstr[2] == 0xBFU) {
@@ -121,7 +123,7 @@ uint16_t *utf8_to_utf16(LIBMTP_mtpdevice_t *device, const char *localstr)

   unicstr[0]='\0';
   unicstr[1]='\0';
-
+  #if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_H)
   /* Do the conversion.  */
   nconv = iconv(params->cd_locale_to_ucs2, &stringp, &convlen, &unip, &convmax);

@@ -130,6 +132,7 @@ uint16_t *utf8_to_utf16(LIBMTP_mtpdevice_t *device, const char *localstr)
     unip[0] = '\0';
     unip[1] = '\0';
   }
+  #endif
   // make sure the string is null terminated
   unicstr[STRING_BUFFER_LENGTH*2] = '\0';
   unicstr[STRING_BUFFER_LENGTH*2+1] = '\0';

Lo and behold, I got it to compile!


I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting https://100daystooffload.com.

#100DaysToOffload #day26 #libmtp