lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
29.27k stars 1.3k forks source link

Support for Windows #19

Closed DullReferenceException closed 9 years ago

DullReferenceException commented 10 years ago

I'd like to be able to use sharp on the Windows platform. Because libvips is available for Windows, I assume that lack of support is mostly in figuring out the build script.

Has this been investigated already? If so, what approaches have already been tried and roadblocks encountered? Knowing what's been tried so far, if anything, will help me or other potential developers come to a working solution quicker.

lovell commented 10 years ago

Hi Jacob, I've yet to try compiling on a Windows machine but am happy to help get it working.

We'll need to add the relevant paths to the libraries and include_dirs directives in binding.gyp plus document how to install the dependencies.

<wishful-thinking> Is there a "standard" location for the .dll files on Windows machines? </wishful-thinking>

Are you using MinGW or similar?

pierreinglebert commented 10 years ago

The easiest way to compile node addon on windows is to install VS Express and Python 2.7. That worked with other addons.

DullReferenceException commented 10 years ago

Sorry, @lovell, for not responding earlier. I started going with gm for now, but I'm still scared of the whole process spawning behavior, so I do want to continue pursuing this.

I am using MinGW. So far, this is what I've encountered and how far I've gotten:

  1. I manually copied the libvips development files to my MinGW environment.
  2. The '<!@(PKG_CONFIG_PATH="/usr/local/Library/ENV/pkgconfig/10.8:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig" pkg-config --libs vips)' bit in the libraries property for binding.gyp is causing an error that "PKG_CONFIG_PATH is not a recognized command" or something like that. I'm guessing there's a difference in how gyp is invoking the shell maybe? To work around this, I installed pkgconfiglite and reduced this to <!@(pkg-config --libs vips). pkg-config seems to be finding the libraries it needs.
  3. Now, when building, I'm given the error "Cannot open include file: 'vips/vips.h'." Changing the include_dirs settings doesn't seem to have any effect, so I guess you have to do something different for VS builds?

I'm just now learning about gyp, so I'm slowly muddling through this. If you guys have any tips for getting past these issues, I'll be sure to document the steps and maybe update binding.gyp to work for Windows "out of the box"-ish.

DullReferenceException commented 10 years ago

Drat. Even with a given VIPS for Windows distribution, the VS compiler chokes on some GCC-specific code in the vips/buf.h header: "'attribute' : unknown override specifier". I'll have to figure out how to coerce node-gyp into using the MinGW compiler instead of VS.

jcupitt commented 10 years ago

Hi, I'm the libvips maintainer. The gcc-specific code is a bug caused by a dropped patch. Paste this into vips.h or use libvips master:

https://github.com/jcupitt/libvips/commit/44f8b0d8ac6fd43368041a5df283d62d843a32e7

mahnunchik commented 10 years ago

+1

vbauer commented 10 years ago

:+1:

itsananderson commented 10 years ago

If https://github.com/lovell/sharp/issues/74 brings in the gcc fix @jcupitt mentioned, then it sounds like at least one blocker for Windows support will be fixed as soon as that version upgrade goes in.

jcupitt commented 10 years ago

The official vips win32 builds now include a libvips.dll. Would this help? I'm told it works with VS, though I've not tried it myself.

http://www.vips.ecs.soton.ac.uk/supported/7.40/win32/

7.40.10 and later. The nofftw binary does not include libfftw and so is pure LGPL.

(background: although libvips has been able to build a DLL for quite a few years, some of the projects it wraps cannot. 7.40.10 and later leave out all these static-library-only projects and so you get a libvips.dll. This binary cannot load FITS or Matlab files.)

owanturist commented 10 years ago

+1

lovell commented 10 years ago

Hello to the +1s of the Noveo Group and welcome Microsofter @itsananderson.

I'm sure the libvips.dll that includes pre-compiled dependencies will help - I didn't realise it existed.

Would anyone like to have a go at adding it to the work-in-progress shell script that is https://github.com/lovell/sharp/blob/preinstall/preinstall.sh ?

itsananderson commented 10 years ago

Finally had a chance to dig in tonight. Got the preinstall.sh doing a (brittle) download and unzip of the libvips binary. Also updated the binding.gyp to conditionally use relative paths to for lib and includes.

https://github.com/itsananderson/sharp/tree/preinstall

This is definitely more proof-of-concept than anything close to being ready to ship, but at least it's a step in the right direction.

After gyp was able to start building, I hit a compile error. Apparently the VS implementation of C++11 doesn't support explicit array initializers. Fixed that (I think), by moving the array initialization into the struct's constructor body. Not super comfortable in C++, so there may be a better way to do that.

I also added a reference to <algorithm> for std:min and std:max. That should be something we can hide behind a compile time flag.

Once those issues were gone, I got a new error during linking:

..\vips-dev-7.40.11\bin\libvips-38.dll : fatal error LNK1107: invalid or corrupt file:
    cannot read at 0x2E0 [c:\sharp\build\sharp.vcxproj]

I also tried libvipsCC-38.dll, but got the same result. At this point I'm quite far outside my knowledge of C++ and node-gyp. I don't think that file is actually corrupted (tried re-downloading), but maybe gyp is expecting a .lib instead of a .dll?

jcupitt commented 10 years ago

Hi @itsananderson, yes at compile-time you need to link against lib/libvipsCC-38.dll.a. The DLL itself, in bin/libvipsCC-38.dll, is for run-time. You can also link against lib/libvipsCC-38.a if you want a static dependency.

You'll need to test carefully, unfortunately. I made the DLL on a linux machine using a cross-compiler that implements something like VC6. The DLL will link to the system msvcrt.dll for the standard library. This means that most resources (file descriptors, memory, almost anything really) must not be allocated in your main binary (which will link to the VS runtime) and freed in libvips. Or vice-versa. You can also have problems if you allocate a file handle in one binary and use it in another, since the two runtimes will have different buffers.

This is very unfortunate :-( I hope it doesn't cause too many problems for you.

itsananderson commented 10 years ago

Ah, thanks. I just tried linking against lib/libvipsCC.dll.a and lib/libvipsCC.a, and it didn't complain about a corrupted file, but then it complained about unresolved symbols:

common.obj : error LNK2001: unresolved external symbol vips_foreign_is_a [c:\sh
arp\build\sharp.vcxproj]
common.obj : error LNK2001: unresolved external symbol vips_pngload_buffer [c:\
sharp\build\sharp.vcxproj]
common.obj : error LNK2001: unresolved external symbol vips_jpegload_buffer [c:
\sharp\build\sharp.vcxproj]
common.obj : error LNK2001: unresolved external symbol vips_webpload_buffer [c:
\sharp\build\sharp.vcxproj]
common.obj : error LNK2001: unresolved external symbol vips_pngload [c:\sharp\b
uild\sharp.vcxproj]
common.obj : error LNK2001: unresolved external symbol vips_magickload [c:\shar
p\build\sharp.vcxproj]
common.obj : error LNK2001: unresolved external symbol vips_jpegload [c:\sharp\
build\sharp.vcxproj]
common.obj : error LNK2001: unresolved external symbol vips_webpload [c:\sharp\
build\sharp.vcxproj]

... and so on

Basically, it's the same errors as when I completely leave out the reference to the libvips binary.

jcupitt commented 10 years ago

Yes, libvipsCC-38.dll.a has the symbols for the C++ wrapper for libvips. You'll need to link against libvips-38.dll.a to get the symbols for the base C library as well.

You'll probably find you need a few other libraries as well. There's a sample build line here:

http://www.vips.ecs.soton.ac.uk/index.php?title=Supported#Development_on_Windows

lovell commented 10 years ago

Thanks @itsananderson, I've added the required source code changes you discovered to master.

It looks like you've made good progress with the linking side of things too, great news.

Are you able to get pkg-config working with MSVC? That should simplify the include_dirs and libraries directives in binding.gyp.

itsananderson commented 10 years ago

I've tried getting pkg-config working on Windows. It runs, and outputs the "right" flags, but it looks like the VS build system expects different inputs. e.g.

LINK : warning LNK4044: unrecognized option '/DMAGICKCORE_HDRI_ENABLE=0 -DMAGIC
KCORE_QUANTUM_DEPTH=16 -D_DLL -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_D
EPTH=16 -D_DLL -mms-bitfields -Ivips\include -Ivips\include\libgsf-1 -Ivips\inc
lude\libxml2 -Ivips\include -Ivips\include\ImageMagick-6 -Ivips\include -Ivips\
include\openslide -Ivips\include\pango-1.0 -Ivips\include\freetype2 -Ivips\incl
ude -Ivips\include\libpng14 -Ivips\include -Ivips\include\glib-2.0 -Ivips\lib\g
lib-2.0\include.lib'; ignored [c:\sharp\build\sharp.vcxproj]

I think manual configuration of libs and include_dirs may, unfortunately, be required (unless there's an easy way to do compatibility conversion).

Still getting a bunch of errors like this:

common.obj : error LNK2001: unresolved external symbol vips_foreign_is_a [c:\sh
arp\build\sharp.vcxproj]

These errors make it seem like a bunch of vips_* functions are missing from the libvipsCC.dll.a library (or I'm somehow linking it wrong). Not really sure how to debug this :(

lovell commented 10 years ago

The pkg-config output you've included starts with a Windows-style /D flag but then uses *nix-style -D flags. I'm unsure which is "correct" but keeping them consistent may help.

John's comment about linking against libvips-38.dll.a instead of libvipsCC.dll.a should also help you:

You'll need to link against libvips-38.dll.a to get the symbols for the base C library as well.

Thank you for persisting with this. If we can get it working you'll have lots of new friends :)

itsananderson commented 10 years ago

The pkg-config outputs unix style flags, and as far as I can tell, node-gyp adds the windows flags when it creates the .vcxproj, which is why it looks weird. Updated binding.gyp is in my fork if you want to take a look. Nothing too crazy there, except calling out to .cmd scripts for pkg-config because CMD doesn't support defining PKG_CONFIG_PATH inline.

John mentioned libvips-38.dll.a, but it doesn't exist in the win32 zip. The only vips libraries I've found are libvips-38.dll, libvipsCC-38.dll, libvips.a, libvipsCC.a, libvips.dll.a, and libvipsCC.dll.a, all of which I've tried :)

jcupitt commented 10 years ago

Hi, sorry for the delay, I've been away.

Yes, pkg-config outputs flags for the compiler that was used to produce the package which made the .pc file, so mingw for the precompiled vips DLL. You won't be able to use it directly in MSVC, but it might help to see things like library ordering.

You're right, the libvips dll.a does not have the -38 in there, sorry. It should work though! I tried this link line off the vips site:

i686-w64-mingw32-g++ \
        -mms-bitfields -march=i686 \
        -I.../vips-dev-7.40.4/include \
        -I.../vips-dev-7.40.4/include/glib-2.0 \
        -I.../vips-dev-7.40.4/lib/glib-2.0/include \
        hello.cc \
        -L.../vips-dev-7.40.4/lib \
        -lvipsCC -lvips -lgsf-1 -lz -ljpeg -lxml2 -lfftw3 -lm \
        -lMagickWand-6.Q16 -llcms2 \
        -lopenslide -lpangoft2-1.0 -ltiff -lpng14 -lexif \
        -lMagickCore-6.Q16 -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 \
        -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl \
        -o hello.exe

with this program:

#include <iostream>
#include <vips/vips>

int
main( int argc, char **argv )
{
        /* Check arguments.
         */
        if( argc != 3 ) {
                std::cerr << "usage: " << argv[0] << " infile outfile\n";
                exit( 1 );
        }

        try {
                vips::VImage fred( argv[1] );

                fred.invert().write( argv[2] );
        }
        catch( vips::VError e ) {
                e.perror( argv[0] );
        }

        return( 0 );
}

and it works for me, though obviously with mingw rather than MSVC. Hopefully just swap it to MSVC link syntax and you should be done.

Try a tiny vips program and see if you can get that to link.

blowsie commented 9 years ago

I am trying to install the latest version of sharp without any of the above mentioned modifications.

I get the following error

dules\node-gyp\b
in\node-gyp.js" rebuild
The system cannot find the path specified.
'true' is not recognized as an internal or external command,
operable program or batch file.
gyp: Call to 'which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CO
NFIG_LIBDIR || true' returned exit status 1. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (C:\Program Files\nodejs\node_modu
les\npm\node_modules\node-gyp\lib\configure.js:343:16)
gyp ERR! stack     at ChildProcess.emit (events.js:98:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:81
0:12)
gyp ERR! System Windows_NT 6.2.9200

node-gyp works fine on other projects of course, as I have VS and python installed.

Is there anything I can do to test any of these changes or help move this along?

lovell commented 9 years ago

@blowsie Please can you try changing || true to || exit 0 on line 12 of binding.gyp.

michaeldrotar commented 9 years ago

+1

I also tried to npm install sharp and got a similar error to @blowsie

D:\Projects\test\node_modules\sharp>node "D:\Apps\nodejs
\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js"
 rebuild
The system cannot find the path specified.
gyp: Call to 'which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONF
IG_LIBDIR || true' returned exit status 0. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (D:\Apps\nodejs\node_modules\npm\nod
e_modules\node-gyp\lib\configure.js:343:16)
gyp ERR! stack     at ChildProcess.emit (events.js:98:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:810:
12)
gyp ERR! System Windows_NT 6.1.7601
gyp ERR! command "node" "D:\\Apps\\nodejs\\node_modules\\npm\\node_modules\\node
-gyp\\bin\\node-gyp.js" "rebuild"
gyp ERR! cwd D:\Projects\test\node_modules\sharp
gyp ERR! node -v v0.10.32
gyp ERR! node-gyp -v v1.0.1
gyp ERR! not ok

npm ERR! sharp@0.8.3 install: `node-gyp rebuild`
npm ERR! Exit status 1

I tried again, freezing the console just after the package was downloaded, and edited binding.gyp with the above change:

    'variables': {
      'PKG_CONFIG_PATH': '<!(which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONFIG_LIBDIR || exit 0):$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig'
    },

Got a slightly different error:

D:\Projects\test\node_modules\sharp>node "D:\Apps\nodejs
\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js"
 rebuild
The system cannot find the path specified.
gyp: Call to 'which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONF
IG_LIBDIR || exit 0' returned exit status 0. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (D:\Apps\nodejs\node_modules\npm\nod
e_modules\node-gyp\lib\configure.js:343:16)
gyp ERR! stack     at ChildProcess.emit (events.js:98:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:810:
12)
gyp ERR! System Windows_NT 6.1.7601
gyp ERR! command "node" "D:\\Apps\\nodejs\\node_modules\\npm\\node_modules\\node
-gyp\\bin\\node-gyp.js" "rebuild"
gyp ERR! cwd D:\Projects\test\node_modules\sharp
gyp ERR! node -v v0.10.32
gyp ERR! node-gyp -v v1.0.1
gyp ERR! not ok

npm ERR! sharp@0.8.3 install: `node-gyp rebuild`
npm ERR! Exit status 1
lovell commented 9 years ago

@michaeldrotar I think you may be experiencing a different problem to @blowsie as you're not seeing the 'true' is not recognized as an internal or external command... error. It might be that the which executable is not found/available on your system.

The which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONFIG_LIBDIR part of PKG_CONFIG_PATH is applicable for Macs only. We need to work out a portable way of making Windows ignore any error it generates, like the || true command does for Linux.

I now have in my possession a new Windows 8.1 laptop so hope to make a bit more progress with this. Please do keep adding comments to this issue about your own attempts of getting it working as these all help narrow down the problems.

(On a multi-platform note, I managed to get libvips and sharp working on an ARMv6 Raspberry Pi over Christmas. WebP support was the trickiest bit to get working.)

Karnith commented 9 years ago

+1 Would be great to get this working!

connor4312 commented 9 years ago

:+1: would love to move from gm to Sharp for actual good streaming support :D

alex6o commented 9 years ago

+1 :)

blowsie commented 9 years ago

@blowsie Please can you try changing || true to || exit 0 on line 12 of binding.gyp.

How do I go about doing this when I'm running npm install? The files don't exist.

lovell commented 9 years ago

@blowsie Thanks for the reply. You'll need to fork your own copy of the sharp repo, clone it locally then make the change. You should then be able to run npm install inside the cloned repo to prove it works before committing the change and pushing back to Github.

blowsie commented 9 years ago

@lovell thanks!

Unfortunately I get a similar error

Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

D:\Projects\github\sharp>npm install
\
> sharp@0.9.3 install D:\Projects\github\sharp
> node-gyp rebuild

D:\Projects\github\sharp>if not defined npm_config_node_gyp (node "C:\Program Fi
les (x86)\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\
bin\node-gyp.js" rebuild )  else (rebuild)
The system cannot find the path specified.
gyp: Call to 'which brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONF
IG_LIBDIR || exit 0' returned exit status 0. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (C:\Program Files (x86)\nodejs\node_
modules\npm\node_modules\node-gyp\lib\configure.js:343:16)
gyp ERR! stack     at ChildProcess.emit (events.js:110:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:1074
:12)
gyp ERR! System Windows_NT 6.3.9600
gyp ERR! command "node" "C:\\Program Files (x86)\\nodejs\\node_modules\\npm\\nod
e_modules\\node-gyp\\bin\\node-gyp.js" "rebuild"
gyp ERR! cwd D:\Projects\github\sharp
gyp ERR! node -v v0.12.2
gyp ERR! node-gyp -v v1.0.3
gyp ERR! not ok

npm ERR! Windows_NT 6.3.9600
npm ERR! argv "C:\\Program Files (x86)\\nodejs\\\\node.exe" "C:\\Program Files (
x86)\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install"
npm ERR! node v0.12.2
npm ERR! npm  v2.7.4
npm ERR! code ELIFECYCLE
npm ERR! sharp@0.9.3 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the sharp@0.9.3 install script 'node-gyp rebuild'.
npm ERR! This is most likely a problem with the sharp package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get their info via:
npm ERR!     npm owner ls sharp
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     D:\Projects\github\sharp\npm-debug.log
lovell commented 9 years ago

Thanks @blowsie it looks like you and @michaeldrotar are now experiencing a consistent error.

I suspect it's the (lack of) which command that's causing the problem now.

Are you able to change which brew ... to where brew ... at the start of that command? (This will break Mac/Linux compatibility so this change is only to discover what the next wall we'll hit on Windows is.)

blowsie commented 9 years ago

Sure, here we go..

After a thorough reading of the comments It seems this variable issue is just the tip of the iceberg.

D:\Projects\github\sharp>npm install

> sharp@0.9.3 install D:\Projects\github\sharp
> node-gyp rebuild

D:\Projects\github\sharp>if not defined npm_config_node_gyp (node "C:\Program Fi
les (x86)\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\
bin\node-gyp.js" rebuild )  else (rebuild)
The system cannot find the path specified.
gyp: Call to 'where brew >/dev/null 2>&1 && eval $(brew --env) && echo $PKG_CONF
IG_LIBDIR || exit 0' returned exit status 0. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (C:\Program Files (x86)\nodejs\node_
modules\npm\node_modules\node-gyp\lib\configure.js:343:16)
gyp ERR! stack     at ChildProcess.emit (events.js:110:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:1074
:12)
.......................................
connor4312 commented 9 years ago

Perhaps moving to a Python build script would work better. Python is required for gyp, so users will have it, and you can do some more intelligent platform-specific handling as needed there...

lovell commented 9 years ago

@connor4312 Great suggestion, thank you. I often look for excuses to use Python so not sure why that hasn't come up as an idea before.

lovell commented 9 years ago

@blowsie thanks for persisting. I'm typing this on a Windows machine whilst waiting for Visual Studio to install and hope to make some progress with this over the Easter weekend.

connor4312 commented 9 years ago

I'm not a C/++'er, but I'm pretty competent with Python; if there's anything in particular I can help out with getting builds working, let me know. Still would love to be able to move our application over to Sharp :)

lovell commented 9 years ago

I've made some progress with this. With a couple of code and config changes I can get sharp to compile on a Windows 8 machine using MSVC via a simple npm install but it's failing at link time.

The problem I've hit is that the Windows dist of vips-dev provides the import library as a .a file, suitable for GCC. What MSVC needs is ideally a .lib or at a minimum a .def file (Visual Studio's lib.exe tool can reverse-engineer a .lib from a .def).

@jcupitt Are you able to generate and therefore provide a libvips.def file in the distribution? http://www.mingw.org/wiki/msvc_and_mingw_dlls suggests it can be extracted via GCC's --output-def flag.

lovell commented 9 years ago

I was wrong - it looks like the MSVC linker can handle .a import libraries. The problem is that it expects 64 bit libraries by default despite compiling everything for 32 bit.

The npm_config_arch environment variable set npm_config_arch=ia32 ensures node-gyp generates a vcxproj file set up for 32 bit linking, so we're past this hurdle.

Next update in a couple of days...

lovell commented 9 years ago

The "judgement" branch of sharp (the forthcoming v0.10.0 release) now compiles, links and most importantly works with the 32-bit x86 version of Node.js and io.js on Windows. (I can't get the 64-bit versions to work; that's a problem for another day.)

Please follow the pre-install instructions at https://github.com/lovell/sharp/tree/judgement#windows then install via:

npm install lovell/sharp#judgement

For node-gyp to work on Windows you'll need Python 2.7.3 and Microsoft Visual Studio C++ 2013 installed.

For those wanting more detail of the solution, the code changes are in https://github.com/lovell/sharp/commit/ce6813329b30f58fa6547c81f3839472fdaeb8e7 and the config changes are in https://github.com/lovell/sharp/commit/f1ad1216cafcc648ccf570419a788e0e4b9ff0ad

A big thank you for all your help and contributions to this issue over the last 12 months!

blowsie commented 9 years ago

Great news, I look forward to testing!

mvictoras commented 9 years ago

Lovely! Worked for me, had to "force 32bit" by running npm install --arch=ia32.

lovell commented 9 years ago

@mvictoras Was the use of --arch=ia32 required using the 32 or 64-bit version of Node.js?

mvictoras commented 9 years ago

The 32-bit version.

On Wed, Apr 15, 2015 at 12:36 PM, Lovell Fuller notifications@github.com wrote:

@mvictoras https://github.com/mvictoras Was the use of --arch=ia32 required using the 32 or 64-bit version of Node.js?

— Reply to this email directly or view it on GitHub https://github.com/lovell/sharp/issues/19#issuecomment-93494915.

Victor Mateevitsi PhD Candidate - University of Illinois at Chicago http://www.uic.edu/ Research Assistant - Electronic Visualization Laboratory http://www.evl.uic.edu/ mvictoras@gmail.com www http://www.vmateevitsi.com | LinkedIn http://www.linkedin.com/pub/5/919/845 | Twitter http://twitter.com/mvictoras | UIC http://www.uic.edu | EVL http://www.evl.uic.edu

Trixt0r commented 9 years ago

I get the following error when I try to build sharp on a win32 platform (environment variables are set correctly):

resize.obj : error LNK2001: unresolved external symbol _vips__image_sizeof_bandformat [C:\Users\trixt\dropclient\app\node_modules\dropclient-image\node_modules\sharp\build\sharp.vcxproj] C:\Users\trixt\dropclient\app\node_modules\dropclient-image\node_modules\sharp\build\Release\sharp.node : fatal error LNK1120: 1 unresolved externals [C:\Users\trixt\dropclient\app\node_modules\ dropclient-image\node_modules\sharp\build\sharp.vcxproj]

The build process worked last Friday... I am building the 32 bit version on Win 10 x64 TP.

Edit: This commit breaks it for me... f72435c750fee26cd7095be507168fe19401253c works without problems.

-Trixt0r

lovell commented 9 years ago

@Trixt0r The error LNK2001: unresolved external symbol looks like a 32 vs 64 bit thing, especially as vips__image_sizeof_bandformat uses 64 bit integers (a "long long" in Windows parlance). Have you tried @mvictoras' suggestion of the --arch=ia32 flag with npm?

"The build process worked last Friday"

Does this mean that you had everything working but now it's not? If so, what has changed, e.g. new commits on sharp's judgement branch since commit x?

Trixt0r commented 9 years ago

The --arch=ia32 flag doesn't change anything. My edit shows, which commit works and which not. Thanks for the fast reply!

lovell commented 9 years ago

@Trixt0r Thank you for narrowing it to a single commit. I can reproduce this problem, which I believe is related to the use of vips_linear1 introduced in dce36e0.

I notice vips__image_sizeof_bandformat was removed in commit https://github.com/jcupitt/libvips/commit/7495690cd6cf387c76a6043897bbbf765a0dc846 earlier today. @jcupitt was this coincidence or in response to this discussion?

jcupitt commented 9 years ago

@lovell yes, I noticed the references to vips__image_sizeof_bandformat and remembered that external variables like that were bad in DLLs. I swapped it for a function call: it should be safer and easier to maintain. The array is still there for compatibility.

vips8 will be frozen very, very soon (I hope, anyway) so it's good to knock warts like this out before that happens.

lovell commented 9 years ago

Thanks John.

There's probably an option to allow the MS C++ linker to work with C variables in DLLs but I don't know MSVC well enough. Can anyone help?

What I can do for now is temporarily wrap the new normalise code in #ifndef _WIN32 to hide it from the linker.

jcupitt commented 9 years ago

It used to be the case that DLLs just did not support external variables, only external functions.

DLLs worked like this: a set of stubs would be added to the calling object, one for each entry point in the DLL. Each stub was initialised with a JMP to linking code. At runtime, if execution hit one of these things, it would trigger the linking routine to load the DLL into memory, if it wasn't already loaded, then to search it for the target function, and then to modify the stub to be a direct jump to the target. This is straightforward to implement and means there's no need for a full run-time linker, as you find on *nixes. The downside is that it can only support simple forward linking of function calls; you can't link external variables, and you can't do things like back linking.

Perhaps the situation has improved since I last looked at this.