libjpeg-turbo / libjpeg-turbo

Main libjpeg-turbo repository
https://libjpeg-turbo.org
Other
3.74k stars 1.02k forks source link

windows x64 static library for libjpeg-turbo with Visual Studio 2015 #45

Closed unktomi closed 8 years ago

unktomi commented 8 years ago

The prebuilt binaries get linkage errors with Visual Studio 2015

Error   LNK2019 unresolved external symbol _snprintf_s referenced in function   setDecompDefaults   XIO E:\xio6\XIO\Intermediate\ProjectFiles\turbojpeg-static.lib(turbojpeg.c.obj) 

Error   LNK2019 unresolved external symbol __iob_func referenced in function output_message XIO E:\xio6\XIO\Intermediate\ProjectFiles\turbojpeg-static.lib(jerror.c.obj)    1   

The Cmake generated VS solution also produces link errors although it seems to be due to misconfiguration in that case) , e.g:

Error   LNK1181 cannot open input file 'E:\GitHub\libjpeg-turbo\simd\Release\jfdctflt-sse-64.obj'   jpeg-static E:\GitHub\libjpeg-turbo\LINK

Here was my cmake command line:

cmake -G"Visual Studio 14 2015 Win64" .
blucz commented 8 years ago

I had the same issue with the prebuilt binaries, but was able to get through a VS2015 build of libjpeg-turbo 1.4.2 using CMake 3.4.3.

I made one change: in simd/CMakeLists.txt to point it to the location of NASM:

set(NASM "C:\\Users\\brian\\AppData\\Local\\nasm\\nasm.exe")

And this fixed the build issues in the simd project.

dcommander commented 8 years ago

I haven't had time to look into this yet, because it's going to require installing VS 2015. It's on my things-to-do list before the libjpeg-turbo 1.5 release.

blucz commented 8 years ago

Yeah, no worries. Thanks for doing what you're doing. As far as I can see it worked once I helped it find NASM, so there might be very little (or just documentation) to be done here.

dcommander commented 8 years ago

I can reproduce the second issue if NASM isn't in the PATH, although the error you posted is a secondary effect. The actual error, which you have to scroll way back in order to see, is under the "simd" target:

  'nasm' is not recognized as an internal or external command,
  operable program or batch file.

The most friendly way to work around this, rather than editing CMakeLists.txt, is to simply pass the path of NASM on the CMake command line:

cmake -G"Visual Studio 14 2015 Win64" -DNASM=c:\\path\\to\\nasm.exe {source_directory}

or simply run cmake-gui after the fact, edit the NASM variable, and re-generate the project files. Or add the path to nasm.exe to your global PATH environment. The same is true when using other versions of Visual Studio as well, not just 2015.

Still investigating the first issue.

dcommander commented 8 years ago

RE: the first issue, you can get rid of the unresolved _snprintf_s symbol error by linking with legacy_stdio_definitions.lib. However, the second error ("unresolved external symbol __iob_func") is not easily solvable. It's due to the new "universal C runtime" (ucrt) library that Microsoft introduced recently. Unfortunately that new library introduces some pretty major incompatibilities with previous Microsoft CRT's.

Referring to http://www.libjpeg-turbo.org/Documentation/OfficialBinaries, it has never been possible to fully isolate the CRT in libjpeg-turbo, because two of the libjpeg API functions (jpeg_stdio_dest() and jpeg_stdio_src()) require passing a FILE handle from the calling program to the library. If the libjpeg API library is being used as a DLL (jpeg62.dll), then the calling program must share the same CRT DLL as jpeg62.dll, or else passing a FILE handle from one to the other wouldn't work (the FILE pointer would point to an opaque structure in either the memory space of the application or the DLL, so the pointer would be meaningless to the other.)

Traditionally, it was possible to link with the static libjpeg-turbo libraries, even when using a different version of Visual C++ than the one used to compile the libraries, but apparently that has never been supported (https://connect.microsoft.com/VisualStudio/feedback/details/1144980/error-lnk2001-unresolved-external-symbol-imp-iob-func) and worked only because the CRT's in different versions of Visual C++ were reasonably similar. Apparently all of that went out the window with the introduction of the ucrt. Googling the error message reveals that we're far from the only OSS project suffering from this.

At the moment, these are the only workarounds I know of:

hughperkins commented 8 years ago

switching to libjpeg + jpeg62.dll worked for me. good :-) Would be good to have an official msvc2015 build though, especially cos, I dont know about you, but my msvc2010 express license just expired last week, and seemed like the only option now is msvc 2015 :-P

By the way, gentle preference: please can you consider distributing files via github releases rather than sourceforge?

dcommander commented 8 years ago

Yeah, I get it, but unless someone wants to donate either the money or the time necessary to get us up and running with Appveyor, providing binaries for multiple Visual Studio releases probably isn't going to be possible anytime soon. So I have to choose one, and no matter which one I choose, someone's going to be unhappy. Personally, I don't like Visual C++ 2015. It's bloated and slow, and I feel that the whole ucrt thing was a mistake. I personally use the command-line version of Visual C++ 2010, which is provided with the (free) Windows 7 SDK, so supporting any GUI version of Visual C++ is something I do only for the community, not for myself. Visual Studio 2008 is still under extended support until 2018 (https://support.microsoft.com/en-us/lifecycle/search?sort=PN&alpha=Visual%20Studio), and Visual Studio 2010 is still under extended support until 2020, so I have to support those versions for a while longer. The reasons why the official binaries are built against VS 2010:

That being said, I do think that a strong case can be made for maintaining binary support for whatever the current version of Visual Studio Express/Community Edition is, since Microsoft doesn't seem to allow for downloading older versions of that software. Again, though, we really need Appveyor to make that happen, since it can automatically spin new builds for all of the Visual Studio releases whenever new commits are checked in.

As far as the file release system, this mailing list message describes my general strategy:

https://sourceforge.net/p/libjpeg-turbo/mailman/libjpeg-turbo-users/thread/55B6D221.4080402@users.sourceforge.net/

I am attempting to use best-of-breed technologies for all aspects of this project, and currently, the file release systems that use GitHub are lacking:

http://michaeltunnell.com/blog/15-miscellaneous/53-14-potential-alternatives-to-sourceforge-for-binary-downloads

hughperkins commented 8 years ago

I personally use the command-line version of Visual C++ 2010, which is provided with the (free) Windows 7 SDK, so supporting any GUI version of Visual C++ is something I do only for the community, not for myself. Visual Studio 2008 is still under extended support until 2018 (https://support.microsoft.com/en-us/lifecycle/search?sort=PN&alpha=Visual%20Studio), and Visual Studio 2010 is still under extended support until 2020

Ah, interesting. I had forgotten about the commandline versoin of vc++2010, assumed it had expired too. Hmmmm, interesting.

One datapoint to note: python 3.5 on Windows uses mvsc2015 as its official compiler, whereas 3.4 was using msvc2010. I'm more or less aligning with this, the python 3.5 compiler choice.

As far as downloads, it looks like you feel it's possible to use sourceforge without inadvertently distributing malware. I have no visibility into this, and simply refuse to run any installer package (exe or similar) from sourceforge. This means, I cannot simply download your packages, but have to spin up a new ec2 instance, unpackage your package, and repackage it...

hughperkins commented 8 years ago

(by the way, after writing https://github.com/libjpeg-turbo/libjpeg-turbo/issues/45#issuecomment-238085487 , it occurs to me that jpeg62.dll is not actually jpeg-turbo? I'm not quite sure. Anyway, I prize my application working slowly, over not working quickly, so will probably just run with jpeg62 for now...)

dcommander commented 8 years ago

libjpeg-turbo is the name of our project and the SDK we distribute. TurboJPEG is the name of one of the two APIs that is supported by this SDK. Please do not confuse the two. jpeg62.dll provides the libjpeg API, not the TurboJPEG API, but it is still fully accelerated. And actually, the MSVC CRT issues are worse with the libjpeg API, because it makes calls to the CRT across DLL boundaries (the TurboJPEG API is self-contained.)

Your malware comments are out of date and incorrect. Please read my mailing list message above, as well as the other article I linked to, as well as this Wikipedia entry, for the whole story. Here are the relevant facts:

In short, there is no possible way that any libjpeg-turbo binaries could become infected, even if SF were still doing DevShare bundling, which they aren't. Please stop spreading this FUD. If another file release platform comes to bear with the same features as SF, I would consider it, but BinTray just isn't there yet, and it's the only one that's close.

hughperkins commented 8 years ago

Hmmmm, actually, I'm getting the following, after linking with jpeglib:

Output file write error --- out of disk space?

jakirkham commented 7 years ago

Not sure if this is of interest to you @hughperkins @dcommander, but we build cross platforms packages of libjpeg-turbo releases at conda-forge for installation with the conda package manager. This includes Windows build for VS 2008, VS 2010, and VS 2015 in addition to Mac and Linux builds. More details can be found at this feedstock.

orellabac commented 5 years ago

The conda libraries worked for me. I just did conda install libjpeg-turbo and in my case everything was in C:\Continuum\anaconda3\pkgs\libjpeg-turbo-2.0.0-hfa6e2cd_0

dcommander commented 4 years ago

The 2.1 evolving pre-releases (https://libjpeg-turbo.org/DeveloperInfo/PreReleases) are now being built with Visual Studio 2015, and the wiki (https://libjpeg-turbo.org/Documentation/OfficialBinaries) has been updated to reflect the fact that, starting with 2.1, it will be necessary to use the DLLs only if using Visual C++ < 2015.

Enjoy!

dcommander commented 3 years ago

Note that, due to an oversight in the official build system, the binaries initially released with libjpeg-turbo 2.1 beta1 were built using Visual Studio 2010. I have fixed that oversight, rebuilt the binaries with Visual Studio 2015, and re-uploaded them to SourceForge.

jakirkham commented 3 years ago

Yeah Visual Studio 2015 (and subsequent versions) have generally made things much easier to maintain on Windows.