openvenues / php-postal

PHP bindings to libpostal for for fast international street address parsing/normalization

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Compile in windows

Sandbird opened this issue · comments

I am trying to compile this in Win10x64 but i am getting ''PHP_POSTAL' is undefined' when i do
configure.bat --disable-all --enable-cli --enable-php-postal
I think its because my config.w32 is wrong.

ARG_WITH("php-postal", "my php-postal", "no");
if (PHP_POSTAL != "no") {
	EXTENSION("php-postal", "php_postal.c", true);
}

Anyone figured out how to compile this in windows ? I want to create a .dll version for php7.0
-Thanks

Nevermind, kinda fixed it. Just remove the
if (PHP_POSTAL != "no") { }
in configure.js....but keep the : EXTENSION("php-postal", "php_postal.c", true);

It still wont compile...
Now getting:

C:\php-sdk\phpdev\vc14\x86\php-7.0.32-src>nmake php_postal.dll

Microsoft (R) Program Maintenance Utility Version 14.00.24210.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Recreating build dirs
Recreating build dirs
   Creating library C:\php-sdk\phpdev\vc14\x86\php-7.0.32-src\x64\Release_TS\php7ts.lib and object C:\php-sdk\phpdev\vc14\x86\php-7.0.32-src\x64\Release_TS\php7ts.exp
   Creating library C:\php-sdk\phpdev\vc14\x86\php-7.0.32-src\x64\Release_TS\php_postal.lib and object C:\php-sdk\phpdev\vc14\x86\php-7.0.32-src\x64\Release_TS\php_postal.exp
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_get_default_options referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_expand_address referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_expansion_array_destroy referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_address_parser_response_destroy referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_get_address_parser_default_options referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_parse_address referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_setup referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_teardown referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_setup_parser referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_teardown_parser referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_setup_language_classifier referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol __imp_libpostal_teardown_language_classifier referenced in function zend_string_init
php_postal.obj : error LNK2019: unresolved external symbol strndup referenced in function zend_string_init
C:\php-sdk\phpdev\vc14\x86\php-7.0.32-src\x64\Release_TS\php_postal.dll : fatal error LNK1120: 13 unresolved externals
NMAKE : fatal error U1077: '"F:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe"' : return code '0x460'
Stop.

@Sandbird, did you successed?

@Sandbird, did you successed?

Unfortunately not. I ended up using the linux version for my testing platform which compiled just fine. Unfortunately my hoster would not help out and install the .so file though....so i decided to abandon the project.

You use ARG_WITH in your config.w32; then you need to use --with-php-postal instead of --enable-php-postal. Furthermore, php-postal depends on libpostal, which you would need to build; and then the dependencies to this lib would have to be setup in config.w32 (CHECK_HEADER_ADD_INCLUDE() and CHECK_LIB()).

I have created config.w32 as follows:

// vim:ft=javascript

ARG_ENABLE("postal", "postal support", "yes");
ARG_WITH("libpostal-dir", "for libpostal support,\n[  --with-libpostal-dir[=DIR]             Set the path to libpostal install prefix.]", "yes");

if (PHP_POSTAL != "no") {
		if (CHECK_LIB("libpostal.lib", "postal", PHP_LIBPOSTAL_DIR) && 
			CHECK_HEADER_ADD_INCLUDE("libpostal.h", "CFLAGS_PHP_POSTAL", PHP_LIBPOSTAL_DIR + "\\src")) {
				MESSAGE("\tpostal build\n\n");
				EXTENSION("postal", "php_postal.c", true);
		} else {
			WARNING("libpostal not enabled; libraries and headers not found");
			PHP_POSTAL = "no"
		}
}

Example of run configure: configure --disable-all --enable-cli --enable-postal --with-libpostal-dir=C:\msys64\home\user\libpostal.

Then edited libpostal.h include path in php_postal.c with relative path shown in configure log, in my case it became #include <../../../../../msys64/home/user/libpostal/src/libpostal.h>.

And edited libpostal.def according to this thread.

And this solved your problem, but now I have this:

php_postal.obj : error LNK2019: unresolved external symbol strndup in function zim_Expand_expand_address

Any suggestions?

I think as quick fix, you can replace all occurrences of strndup in php_postal.c with zend_strndup. However, it seems to me that these allocations should actually use ZendMM.

I think as quick fix, you can replace all occurrences of strndup in php_postal.c with zend_strndup. However, it seems to me that these allocations should actually use ZendMM.

Thanks for the answer, it helped, it seems the extension was compiled.

But now PHP cannot load it.

First, you need the same build type for the extension and for PHP (NTS/ZTS has to match, same VC version, x86/x64 has to match).

Then you have to make sure that all dependencies are available. You can check with deplister.exe php_postal.dll which is contained in the official PHP binaries.

Same( Tried different versions.

Output:

c:\php>deplister.exe ext\php_postal.dll
php7ts.dll,OK
libpostal.dll,OK
VCRUNTIME140.dll,OK
api-ms-win-crt-heap-l1-1-0.dll,OK
api-ms-win-crt-runtime-l1-1-0.dll,OK
KERNEL32.dll,OK

c:\php>php -m | findstr postal
PHP Warning:  PHP Startup: Unable to load dynamic library 'C:\php\ext\php_postal.dll' (tried: C:\php\ext\php_postal.dll (  Warning: PHP Startup: Unable to load dynamic library 'C:\php\ext\php_postal.dll' (tried: C:\php\ext\php_postal.dll (   .), ext\php_C:\php\ext\php_postal.dll.dll (   .)) in Unknown on line 0

deplister output looks good; maybe an issue because libpostal.dll has been compiled/link with MinGW? Did you try to build libpostal as a static lib, and use this?

where do you got the libpostal.dll? have you tried to download the prebuild version from libpostal's build server?

Thank you for answers, I tried with compiled libpostal.dll, and now I tried prebuild and it help to solve one more step, but again an error occurs:
ERR Error loading transliteration module, dir=(null) at libpostal_setup_datadir (libpostal.c:290) errno:No such file or directory PHP Fatal error: Unable to start postal module in Unknown on line 0

Seems that extension doesn't see libpostal data dir and I have no idea where I have to setup it.

@hsh01 i got it compiled and up and running. had the same dir=(null) error as you.

my solution:

  • compile the php ext with your config.w32 (data dir path does not matter)
  • put the build php_postal.dll in your php/ext
  • put the libpostal.dll form appveyor.com to php/ext
  • put the downloaded dat files in C:\libpostal (the appveyor dll is compiled with "C:" as data dir and in the data dir the lib name is appended, so everything should be in C:\libpostal
  • i downloaded libpostal the dat files with a virtual linux machine by simple following the build manual (i wasn't able to find the download urls in the source code but i am sure they are there somewhere)
$expansions = Postal\Expand::expand_address("Quatre vingt douze Ave des Champs-Élysées");
foreach ($expansions as $expansion) {
    echo "$expansion\n";
}

$parsed = Postal\Parser::parse_address("The Book Club 100-106 Leonard St, Shoreditch, London, Greater London, EC2A 4RH, United Kingdom");
foreach ($parsed as $component) {
    echo "{$component['label']}: {$component['value']}\n";
}

test script works now but is really slow. many php operations like php -m php -v are quite slow now.
i think i go for a linux docker image with api.

Thanks, it finally works. Indeed php has become slower. In any case, this is faster than using WSL.

@c33s > According to this, performance issue is not windows only issue.