libxcrypt icon indicating copy to clipboard operation
libxcrypt copied to clipboard

Windows support plan

Open jbcr opened this issue 1 year ago • 9 comments

Hi,

Have you a plan to support Windows?

I'm interested in building on Windows for a PHP extension called xpass.

https://github.com/remicollet/php-xpass

jbcr avatar Sep 25 '24 13:09 jbcr

With a couple of hacks, I've got an apparently successful MSVC build of crypt.lib (static lib), which allowed me to build php-xpass. Any help on properly fixing this so it can be submitted as PR here is welcome!

cmb69 avatar Dec 10 '24 10:12 cmb69

The tests on Windows pass?

I will try to build your version on Windows Intel and ARM64

jbcr avatar Dec 11 '24 09:12 jbcr

@cmb69 Where is the Windows build instruction?

jbcr avatar Dec 11 '24 09:12 jbcr

The tests on Windows pass?

The php-xpass tests were passing. Now I tried to run the libxcrypt test-suite, but had to deactivate a couple of test cases for now, because they either use mmap() (not directly available with MSVC), or strong_alias() (not available with MSVC).

deactivate-tests.patch
 Makefile.am | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 5c07059..08ed7ee 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -368,19 +368,15 @@ check_PROGRAMS = \
 	test/alg-sha256 \
 	test/alg-sha512 \
 	test/alg-yescrypt \
-	test/badsalt \
 	test/badsetting \
 	test/byteorder \
 	test/checksalt \
-	test/compile-strong-alias \
-	test/crypt-badargs \
 	test/crypt-gost-yescrypt \
 	test/explicit-bzero \
 	test/gensalt \
 	test/gensalt-extradata \
 	test/gensalt-nthash \
 	test/getrandom-fallbacks \
-	test/getrandom-interface \
 	test/preferred-method \
 	test/short-outbuf \
 	test/special-char-salt

To unfail alg-yescript, I had to apply:

unfail-alg-yescript.patch
 test/alg-yescrypt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/alg-yescrypt.c b/test/alg-yescrypt.c
index 8112dac..3303368 100644
--- a/test/alg-yescrypt.c
+++ b/test/alg-yescrypt.c
@@ -158,7 +158,7 @@ int main(void)
 {
 	int i;
 
-	setvbuf(stdout, NULL, _IOLBF, 0);
+	// setvbuf(stdout, NULL, _IOLBF, 0);
 
 #ifdef TEST_PBKDF2_SHA256
 	print_PBKDF2_SHA256("password", "salt", 1, 20);

Otherwise the test crashes with MSVC since passing 0 as last argument to setvbuf() is not allowed there (and line buffering can't be enforced by calling setvbuf() anyway).

Afterwards I get:

test-suite.log
   xcrypt 4.4.37: ./test-suite.log
=====================================

# TOTAL: 41
# PASS:  37
# SKIP:  3
# XFAIL: 0
# FAIL:  1
# XPASS: 0
# ERROR: 0

System information (uname -a): MSYS_NT-10.0-19045 3.5.4-0bc1222b.x86_64 2024-09-04 18:28 UTC x86_64
Distribution information (/etc/os-release):
NAME=MSYS2
ID=msys2
PRETTY_NAME="MSYS2"
ID_LIKE="cygwin arch"
HOME_URL="https://www.msys2.org"
BUG_REPORT_URL="https://github.com/msys2/MSYS2-packages/issues"

.. contents:: :depth: 2

SKIP: test/explicit-bzero
=========================

SKIP test/explicit-bzero.exe (exit status: 77)

SKIP: test/getrandom-fallbacks
==============================

SKIP test/getrandom-fallbacks.exe (exit status: 77)

FAIL: test/symbols-static
=========================

+ /bin/sh -c '. ./libcrypt.la; printf %s "$old_library"'
+ '/c/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/HostX64/x64/dumpbin' -symbols --format=bsd --extern-only --defined-only /d/git/libxcrypt/.libs/crypt.lib
*** Missing globals:
  crypt
  crypt_checksalt
  crypt_gensalt
  crypt_gensalt_ra
  crypt_gensalt_rn
  crypt_preferred_method
  crypt_r
  crypt_ra
  crypt_rn
FAIL test/symbols-static.pl (exit status: 1)

SKIP: test/symbols-renames
==========================

symbols-renames.pl: skipping test: cpp -dD not available
SKIP test/symbols-renames.pl (exit status: 77)

The failing symbols-static is expected, since the symbols are not exported on Windows (missing __declspec(dllimport)/__declspec(dllexport). Should look into the skipped tests, but otherwise this looks quite good so far.

I will try to build your version on Windows Intel and ARM64

So far I tried only x64, but not x86, let alone ARM64 (can cross-compile in theory, but have no ARM machine available).

Where is the Windows build instruction?

So far I was reluctant to set that up, since I've only did rough testing, but given the test suite runs pretty well, I've submitted https://github.com/winlibs/winlib-builder/pull/34.

cmb69 avatar Dec 11 '24 15:12 cmb69

@cmb69 I looked https://github.com/winlibs/winlib-builder/pull/34. You use MSYS2 to build the library. Unfortunately, MSYS2 is not available on ARM64 :cry:

jbcr avatar Dec 11 '24 16:12 jbcr

See https://github.com/winlibs/winlib-builder/pull/34#issuecomment-2536793925. I suggest to continue discussion there (unless it's generally related to libxcrypt, of course).

cmb69 avatar Dec 11 '24 18:12 cmb69

With a couple of hacks, I've got an apparently successful MSVC build of crypt.lib (static lib), which allowed me to build php-xpass. Any help on properly fixing this so it can be submitted as PR here is welcome!

I think there are two issues here: compiling on Windows and compiling with MSVC. The former can be done with GCC. I would guess it makes most sense to first get the former to work and then the latter.

Leont avatar Jan 09 '25 17:01 Leont

Building with MinGW GCC works fine (besides that libtool avoids building a shared library on that platform, because there might be undefined symbols, which would cause the build to fail; so need to patch libtool). Only very minor issue:

https://github.com/besser82/libxcrypt/blob/ca1516739ed4021ae7eb5e6a9d26bfff5a660665/lib/util-get-random-bytes.c#L140

MS declares the 3rd parameter to read() as unsigned int (32bit), but size_t is 64bit on x64. Given that it's unlikely that someone would read 4 GiB or more from /dev/urandom, that's not a real issue (can suppress the warning, or patch in a cast).

I'll try to provide a PR (or maybe a couple of PRs) regarding MSVC support.

cmb69 avatar Feb 06 '25 18:02 cmb69

Hello @cmb69 May I ask how is the progress now? I also encountered the build failure when using mingw:

../git/lib/util-get-random-bytes.c: In function '_crypt_get_random_bytes': ../git/lib/util-get-random-bytes.c:140:42: error: conversion from 'size_t' {aka 'long long unsigned int'} to 'unsigned int' may change value [-Werror=conversion] 140 | ssize_t nread = read (fd, buf, buflen); | ^~~~~~

yizhao1 avatar Mar 06 '25 13:03 yizhao1