winlibs / gettext

GNU Translation Project runtime
35 stars 19 forks source link

Unable to build on ARM64 (AARCH64) #1

Open macintoshplus opened 2 months ago

macintoshplus commented 2 months ago

The file header stdint.h contains the line typedef unsigned long long uintmax_t;.

On build this line generate these errors: 

(ClCompile target) -> 
  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\stdint.h(46,28): error C2632: '__int64' followed by '__int64' is illegal [C:\actions-runner\_work\winlib-builder\winlib-builder\gettext\MSVC17\libintl_static\libintl_static.vcxproj]
  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\stdint.h(46,28): error C2632: '__int64' followed by '__int64' is illegal [C:\actions-runner\_work\winlib-builder\winlib-builder\gettext\MSVC17\libintl_static\libintl_static.vcxproj]
  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\stdint.h(46,28): error C2632: '__int64' followed by '__int64' is illegal [C:\actions-runner\_work\winlib-builder\winlib-builder\gettext\MSVC17\libintl_static\libintl_static.vcxproj]
  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\stdint.h(46,28): error C2632: '__int64' followed by '__int64' is illegal [C:\actions-runner\_work\winlib-builder\winlib-builder\gettext\MSVC17\libintl_static\libintl_static.vcxproj]
"C:\actions-runner\_work\winlib-builder\winlib-builder\gettext\MSVC17\gettext.sln" (default target) (1) ->
"C:\actions-runner\_work\winlib-builder\winlib-builder\gettext\MSVC17\libintl_dll\libintl_dll.vcxproj" (default target) (3) ->
  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\stdint.h(46,28): error C2632: '__int64' followed by '__int64' is illegal [C:\actions-runner\_work\winlib-builder\winlib-builder\gettext\MSVC17\libintl_dll\libintl_dll.vcxproj]
  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\stdint.h(46,28): error C2632: '__int64' followed by '__int64' is illegal [C:\actions-runner\_work\winlib-builder\winlib-builder\gettext\MSVC17\libintl_dll\libintl_dll.vcxproj]
  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\stdint.h(46,28): error C2632: '__int64' followed by '__int64' is illegal [C:\actions-runner\_work\winlib-builder\winlib-builder\gettext\MSVC17\libintl_dll\libintl_dll.vcxproj]
  C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.41.34120\include\stdint.h(46,28): error C2632: '__int64' followed by '__int64' is illegal [C:\actions-runner\_work\winlib-builder\winlib-builder\gettext\MSVC17\libintl_dll\libintl_dll.vcxproj]

I have search on Internet without found a solution.

macintoshplus commented 1 month ago

When I apply this patch, the build successed:

diff --git a/source/gettext-runtime/config.h b/source/gettext-runtime/config.h
index cde9f23..f757977 100644
--- a/source/gettext-runtime/config.h
+++ b/source/gettext-runtime/config.h
@@ -614,7 +614,12 @@
 /* Define to unsigned long or unsigned long long if <stdint.h> and
    <inttypes.h> don't define. */
 #ifdef _WIN64
+#ifdef _M_ARM64
+#define uintmax_t unsigned __int32
+#else
 #define uintmax_t unsigned __int64
+#endif
 #else
 #define uintmax_t unsigned __int32
 #endif

But the type is wrong for a 64bits architecture.

I have try to add this code #define uintmax_t2 unsigned __int64 without issues. On other project, I have define #define uintmax_t unsigned __int64 without issues.

I don't understand why this error occur on this project.

macintoshplus commented 1 month ago

I found a solution. This patch work for me with VS17 on ARM64

diff --git a/source/gettext-runtime/config.h b/source/gettext-runtime/config.h
index cde9f23..66cb602 100644
--- a/source/gettext-runtime/config.h
+++ b/source/gettext-runtime/config.h
@@ -221,6 +221,7 @@

 /* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
 /* #undef HAVE_INTMAX_T */
+#define HAVE_INTMAX_T 1

 /* Define to 1 if you have the <inttypes.h> header file. */
 /* #undef HAVE_INTTYPES_H */
@@ -322,10 +323,12 @@

 /* Define to 1 if you have the <stdint.h> header file. */
 /* #undef HAVE_STDINT_H */
+#define HAVE_STDINT_H 1

 /* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
    uintmax_t. */
 /* #undef HAVE_STDINT_H_WITH_UINTMAX */
+#define HAVE_STDINT_H_WITH_UINTMAX 1

 /* Define to 1 if you have the <stdlib.h> header file. */
 #define HAVE_STDLIB_H 1
@@ -613,11 +616,11 @@

 /* Define to unsigned long or unsigned long long if <stdint.h> and
    <inttypes.h> don't define. */
-#ifdef _WIN64
+/*#ifdef _WIN64
 #define uintmax_t unsigned __int64
 #else
 #define uintmax_t unsigned __int32
-#endif
+#endif*/

 #define __libc_lock_t                   gl_lock_t
 #define __libc_lock_define              gl_lock_define
diff --git a/source/gettext-runtime/intl/printf-parse.c b/source/gettext-runtime/intl/printf-parse.c
index 8cedfc6..644b519 100644
--- a/source/gettext-runtime/intl/printf-parse.c
+++ b/source/gettext-runtime/intl/printf-parse.c
@@ -49,7 +49,7 @@

 /* Get intmax_t.  */
 #if _MSC_VER
-# define intmax_t long int
+/*# define intmax_t long int*/
 #elif defined IN_LIBINTL || defined IN_LIBASPRINTF
 # if HAVE_STDINT_H_WITH_UINTMAX
 #  include <stdint.h>
cmb69 commented 1 month ago

Indeed, this config.h is ancient (apparently hasn't been touched since 2015). That needs some work; see also https://github.com/winlibs/libiconv/issues/14.

macintoshplus commented 4 weeks ago

The patch is not necessary for building the library for x86 and x64 processors.

I don't open a PR because I don't how to manage the difference? two config.h?

cmb69 commented 4 weeks ago

I don't think there is the need for two config.h in this case. <stdint.h> is available as of Visual Studio 2010, and I don't think we need to support older versions (actually, I'm fine with only supporting VS 2015 or newer).

However, to me the proper fix seems not to ship any config.h at all, but to create it during build time (another story, though).

cmb69 commented 4 weeks ago

I just tried a similar

patch ````diff source/gettext-runtime/config.h | 16 ++++++++-------- source/gettext-runtime/intl/printf-parse.c | 4 +--- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/source/gettext-runtime/config.h b/source/gettext-runtime/config.h index cde9f23..ffa8e2a 100644 --- a/source/gettext-runtime/config.h +++ b/source/gettext-runtime/config.h @@ -220,7 +220,7 @@ /* #undef HAVE_INCLUDE_NEXT */ /* Define if you have the 'intmax_t' type in or . */ -/* #undef HAVE_INTMAX_T */ +#define HAVE_INTMAX_T 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_INTTYPES_H */ @@ -321,11 +321,11 @@ #define HAVE_STDDEF_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_STDINT_H */ +#define HAVE_STDINT_H 1 /* Define if exists, doesn't clash with , and declares uintmax_t. */ -/* #undef HAVE_STDINT_H_WITH_UINTMAX */ +#define HAVE_STDINT_H_WITH_UINTMAX 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 @@ -613,11 +613,11 @@ /* Define to unsigned long or unsigned long long if and don't define. */ -#ifdef _WIN64 -#define uintmax_t unsigned __int64 -#else -#define uintmax_t unsigned __int32 -#endif +// #ifdef _WIN64 +// #define uintmax_t unsigned __int64 +// #else +// #define uintmax_t unsigned __int32 +// #endif #define __libc_lock_t gl_lock_t #define __libc_lock_define gl_lock_define diff --git a/source/gettext-runtime/intl/printf-parse.c b/source/gettext-runtime/intl/printf-parse.c index 8cedfc6..0e2d2c7 100644 --- a/source/gettext-runtime/intl/printf-parse.c +++ b/source/gettext-runtime/intl/printf-parse.c @@ -48,9 +48,7 @@ #include /* Get intmax_t. */ -#if _MSC_VER -# define intmax_t long int -#elif defined IN_LIBINTL || defined IN_LIBASPRINTF +#if defined IN_LIBINTL || defined IN_LIBASPRINTF # if HAVE_STDINT_H_WITH_UINTMAX # include # endif ````

and ran

msbuild gettext.sln /p:Configuration=Release /p:Platform=x64 /p:PlatformToolset=v141 /p:WindowsTargetPlatformVersion=10.0.20348.0

and that seems to work fine (would need to install some older toolset and WinSDK, and do some real tests, though).

I'm not sure though if it's worth fiddling with the ancient gettext 0.18.3 we still use.

macintoshplus commented 4 weeks ago

I have read the original repository of gettext. It is not easy to extract the build logical to make port on windows. I don’t have experience to do this.

What is the interest to build the library with older VS version? Update libintl on supported versions?

For ARM64 I want only build PHP 8.4 and newer.

cmb69 commented 4 weeks ago

Well, supporting older versions of Visual Studio may not be required; not 100% sure, since at least some of the winlib repos are apparently used by others.

And yeah, it seems to me the only sustainable way to be able to do regular updates would be to use Cygwin or MSYS2 to do the configuration and builds. See https://github.com/winlibs/winlib-builder/pull/24 (which is about libiconv, but gettext should be pretty much the same).

Note that @mlocati, who provides the official gettext and iconv Windows builds, also uses a Cygwin toolchain (compiling and linking is apparently done with MinGW).

mlocati commented 4 weeks ago

I'm building the gettext binaries with mingw-w64 on cygwin. There's a doc that list the supported ways to build gettext for Windows: see https://git.savannah.gnu.org/gitweb/?p=gettext.git;a=blob;f=INSTALL.windows;h=3aa1c004a63005da4f356eee4345c1d493ae3433;hb=HEAD

PS: In the future I'm planning to distribute .h.and .lib files too for people using Visual Studio (and that will require building with MS Visual C).

cmb69 commented 4 weeks ago

@mlocati, building with MSVC is indeed what I'm trying to do. The instructions in INSTALL.windows have been helpful, but I didn't want to setup the MSVC environment manually; that appears to be tedious and error-prone (INSTALL.windows seems to mix headers from Windows Kits\10\Include\10.0.10240.0 and Windows Kits\8.1\Include). Thus, I basically call vcvarsall.bat and then the login shell of msys2 (the "ignoble and ignominious hack" can easily be disabled). That sets up a working build environment. However, I've noticed that the build calls windres/gcc instead of rc.exe/cvtres.exe, so I've set up a minimalist windres wrapper (neither general enough nor production ready to provide upstream). There are a couple of yet unresolved issues (such as missing .pdb files), but it's basically working for libiconv.

@macintoshplus, maybe you are interested in checking the libiconv arm64 build.

mlocati commented 4 weeks ago

Maybe @bhaible can shed some light

bhaible commented 4 weeks ago

@cmb wrote:

However, to me the proper fix seems not to ship any config.h at all, but to create it during build time

Yes. That's the whole point of GNU Autoconf.

msys2 (the "ignoble and ignominious hack" can easily be disabled)

With that hack disabled, you are a step closer to a reliable build. In any case, I recommend to look at the test failures (both in gettext-tools/tests/ and in gettext-tools/gnulib-tests/).