Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZLIB_LIBRARY ZLIB_INCLUDE_DIR being ignored (LNK2019 errors) in OpenEXR\IlmImf\IlmImf.vcxproj #379

Closed
mprevot opened this issue Apr 15, 2019 · 17 comments
Labels
Needs Discussion To be discussed in the technical steering committee

Comments

@mprevot
Copy link

mprevot commented Apr 15, 2019

In windows 10 x64; using VS2017; using cmake 3.13.14 and a powershell script.

I have multiple LNK2019 error, despite a correct configuration:

ImfDwaCompressor.obj : error LNK2019: unresolved external symbol compress2 referenced in function "private: int __cdecl
 Imf_2_3::DwaCompressor::compress(char const *,int,class Imath_2_3::Box<class Imath_2_3::Vec2<int> >,char const * &)" (
?compress@DwaCompressor@Imf_2_3@@AEAAHPEBDHV?$Box@V?$Vec2@H@Imath_2_3@@@Imath_2_3@@AEAPEBD@Z) [I:\lib\master-openexr\bu
ild\OpenEXR\IlmImf\IlmImf.vcxproj]
ImfDwaCompressor.obj : error LNK2019: unresolved external symbol compressBound referenced in function "private: int __c
decl Imf_2_3::DwaCompressor::compress(char const *,int,class Imath_2_3::Box<class Imath_2_3::Vec2<int> >,char const * &
)" (?compress@DwaCompressor@Imf_2_3@@AEAAHPEBDHV?$Box@V?$Vec2@H@Imath_2_3@@@Imath_2_3@@AEAPEBD@Z) [I:\lib\master-openex
r\build\OpenEXR\IlmImf\IlmImf.vcxproj]
ImfDwaCompressor.obj : error LNK2019: unresolved external symbol uncompress referenced in function "private: int __cdec
l Imf_2_3::DwaCompressor::uncompress(char const *,int,class Imath_2_3::Box<class Imath_2_3::Vec2<int> >,char const * &)
" (?uncompress@DwaCompressor@Imf_2_3@@AEAAHPEBDHV?$Box@V?$Vec2@H@Imath_2_3@@@Imath_2_3@@AEAPEBD@Z) [I:\lib\master-opene
xr\build\OpenEXR\IlmImf\IlmImf.vcxproj]
ImfPxr24Compressor.obj : error LNK2001: unresolved external symbol uncompress [I:\lib\master-openexr\build\OpenEXR\IlmI
mf\IlmImf.vcxproj]
ImfZip.obj : error LNK2001: unresolved external symbol uncompress [I:\lib\master-openexr\build\OpenEXR\IlmImf\IlmImf.vc
xproj]
ImfPxr24Compressor.obj : error LNK2019: unresolved external symbol compress referenced in function "private: int __cdec
l Imf_2_3::Pxr24Compressor::compress(char const *,int,class Imath_2_3::Box<class Imath_2_3::Vec2<int> >,char const * &)
" (?compress@Pxr24Compressor@Imf_2_3@@AEAAHPEBDHV?$Box@V?$Vec2@H@Imath_2_3@@@Imath_2_3@@AEAPEBD@Z) [I:\lib\master-opene
xr\build\OpenEXR\IlmImf\IlmImf.vcxproj]
ImfZip.obj : error LNK2001: unresolved external symbol compress [I:\lib\master-openexr\build\OpenEXR\IlmImf\IlmImf.vcxp
roj]
I:\lib\master-openexr\build\OpenEXR\IlmImf\Release\IlmImf-2_3.dll : fatal error LNK1120: 4 unresolved externals [I:\lib
\master-openexr\build\OpenEXR\IlmImf\IlmImf.vcxproj]

Repro:
using zlib 1.2.11, compiled in Win64 at I:\lib\zlib

I configure and build openexr with this script:

$target = "Visual Studio 15 2017 Win64"
$zlib_prefix = "I:\lib\zlib"

function configure {
	cmake.exe -G $target -T v141, host=x64 -j8 `
		-DZLIB_LIBRARY="${zlib_prefix}\lib" -DZLIB_INCLUDE_DIR="${zlib_prefix}\include" `
		-DOPENEXR_BUILD_PYTHON_LIBS=0 -DCMAKE_INSTALL_PREFIX="I:\lib\openexr" `
		..
}

function build {
	"build openexr debug"
	MSBuild.exe OpenEXR.sln /verbosity:m /m
	"build openexr release"
	MSBuild.exe OpenEXR.sln /p:Configuration=Release /verbosity:m /m
}

function install {
	"install openexr debug"
	MSBuild.exe INSTALL.vcxproj /verbosity:m /m
	"install openexr release"
	MSBuild.exe INSTALL.vcxproj /p:Configuration=Release /verbosity:m /m
}

if (!(test-path build)) {
	New-Item -ItemType Directory build
}
Set-Location build
configure
build
#install
Set-Location ..

Proof: hand-edit IlmImf.vcxproj to use the zlib.lib and zlibd.lib provided works.

@meshula
Copy link
Contributor

meshula commented Apr 15, 2019

apparent the cmake zlib find script looks for a ZLIB_ROOT variable?

https://github.com/Kitware/CMake/blob/master/Modules/FindZLIB.cmake

@mprevot
Copy link
Author

mprevot commented Apr 16, 2019

@meshula Indeed, first, but ZLIB_LIBRARY ZLIB_INCLUDE_DIR are evaluated after (it seems they are not in the end) and they used by other projects correctly and are documented.

@meshula
Copy link
Contributor

meshula commented Apr 16, 2019

That's true. The link errors don't explain why the symbols are missing. Could you attach your CMakeCache.txt file? It might provide some clues about what's going on.

@mprevot
Copy link
Author

mprevot commented Apr 17, 2019

CMakeCache.txt

@mprevot
Copy link
Author

mprevot commented Apr 17, 2019

@meshula last line of the OP:

Proof: hand-edit IlmImf.vcxproj to use the zlib.lib and zlibd.lib provided works.

@mprevot
Copy link
Author

mprevot commented Apr 17, 2019

@meshula Adding -DZLIB_ROOT="I:\lib\zlib" in the configure command (cmake.exe -G $target -T v141, host=x64 -j16 ...) does not solve the problem any better.

@meshula
Copy link
Contributor

meshula commented Apr 17, 2019

Thanks for posting the file. I don't have any more information for you yet. One more question, are you building from github top of tree, or from source obtained some other way?

@mprevot
Copy link
Author

mprevot commented Apr 17, 2019

Yes. I downloaded the sources from master the 14th of april.

@meshula
Copy link
Contributor

meshula commented Apr 18, 2019

I wanted to double check if OpenEXR can be built at all with zlib when both are fetched fresh. I did the following:

cd c:\Projects\Lucasfilm
git clone https://github.com/madler/zlib.git
cd c:\Projects\Lucasfilm\build\zlib
cmake -G "Visual Studio 15 2017 Win64" c:\Projects\Lucasfilm\zlib -DCMAKE_INSTALL_PREFIX=c:\Projects\Lucasfilm\install
cmake --build . --config Release --target install
cd c:\Projects\Lucasfilm
git clone https://github.com/openexr/openexr.git
cd build\openexr
cmake -G "Visual Studio 15 2017 Win64" -DOPENEXR_BUILD_PYTHON_LIBS=OFF -DOPENEXR_ENABLE_TESTS=OFF -DCMAKE_INSTALL_PREFIX=c:\Projects\Lucasfilm\install ..\..\openexr
cmake --build . --config Release --target install

and I got a successful build. The primary difference is that I asked cmake to install zlib into the directory I will build openexr into, and relied on the CMAKE_INSTALL_PREFIX variable to help cmake find the zlib installation. I am wondering if you could attempt the same, to try to isolate first of all whether you are able to build at all?

@mprevot
Copy link
Author

mprevot commented Apr 18, 2019

As I mentionned in the OP, I added in the IlmImf project the path I:\lib\zlib\lib to search lib files (*.lib) and zlib.lib and zlibd.lib (for debug build) references by hand and this allows a successful build.

This is what I meant by:

Proof: hand-edit IlmImf.vcxproj to use the zlib.lib and zlibd.lib provided works.

The problem is that ZLIB_LIBRARY ZLIB_INCLUDE_DIR are being ignored since they should be added in the IlmImf project to allow the successful build. IMO CMakeLists.txt needs few corrections.

@meshula
Copy link
Contributor

meshula commented Apr 18, 2019

Yes, I did see your original comment, and reminders on that point. The cmake scripts have undergone significant revision recently and regressions are possible. My point is to establish if a conventional build works, or if it is necessary to patch a conventional build as well. I'm now satisfied that the conventional build does work as expected, and so agree with you that revisions are possible to support your configuration.

@meshula
Copy link
Contributor

meshula commented Apr 19, 2019

Okay, I went through all the documentation I could find, and the implementation, and compared a bunch of projects on github, some of which do indeed use ZLIB_LIBRARY as an input.

quick summary

  1. ZLIB_LIBRARIES is the variable to set, according to the documentation, and it's what OpenEXR expects. I think this is the right thing to do, even if some projects don't do it.
  2. OpenEXR erroneously uses ZLIB_INCLUDE_DIR, which is an error in the OpenEXR Cmake files and should be corrected.

details:

https://cmake.org/cmake/help/latest/module/FindZLIB.html

OpenExr looks for ZLIB_INCLUDE_DIR in OpenEXR/CMakeLists.txt, but according to the FindZLIB documentation, it should be looking for ZLIB_INCLUDE_DIRS.

 MACRO(SET_ILMBASE_INCLUDE_DIRS _target)
    TARGET_INCLUDE_DIRECTORIES(${_target}
     PRIVATE ${ZLIB_INCLUDE_DIR}
     PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../config
     PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../../IlmBase/config

So this is an error in OpenEXR's cmake scripts.

According to the documentation, using ZLIB_ROOT should be sufficient to set ZLIB_INCLUDE_DIRS and ZLIB_LIBRARIES. Nonetheless, since you only had to edit the vcxproj to add zlib references, setting -DZLIB_LIBRARIES in your script instead of ZLIB_LIBRARY should solve your problem.

I understand that other projects are successfully using ZLIB_LIBRARY, but the implementation itself

https://github.com/Kitware/CMake/blob/master/Modules/FindZLIB.cmake

specifies ZLIB_LIBRARY as an input to FindZLIB, used to set ZLIB_LIBRARIES.

Result Variables
^^^^^^^^^^^^^^^^

This module defines the following variables:

::

  ZLIB_INCLUDE_DIRS   - where to find zlib.h, etc.
  ZLIB_LIBRARIES      - List of libraries when using zlib.
  ZLIB_FOUND - True if zlib found.

As an interesting point in comparison, conan's FindZlib script was updated to use ZLIB_LIBRARIES only, which broke some of their dependent packages, so they had to add ZLIB_LIBRARY back in as an exposed variable. https://github.com/conan-community/community/issues/153 They too preferred to stick to documented outputs.

@mprevot
Copy link
Author

mprevot commented Apr 23, 2019 via email

@meshula
Copy link
Contributor

meshula commented Apr 23, 2019

Great :) Glad to hear you are unblocked!

@cary-ilm
Copy link
Member

@meshula, has this been fixed with recent CMake change?

@cary-ilm cary-ilm added the Needs Discussion To be discussed in the technical steering committee label Jun 26, 2019
@meshula
Copy link
Contributor

meshula commented Jun 27, 2019

We need to apply the fix, it hasn't been done yet.

@kdt3rd
Copy link
Contributor

kdt3rd commented Jul 18, 2019

With the newly checked in refactor of the cmake stuff (hit master just in the past 24 hours), it uses the the (cmake generated) zlib "imported" library mechanism and sets target_link_libraries to add zlib, which then automatically transports appropriate compile flags, include directories, and link flags / paths from the zlib "library" that FindZLIB makes. So via the mechanisms and search locations documented in the FindZLIB.cmake in the cmake Modules folder, once zlib is found and defined as an imported library by that script, we are no longer specifying paths manually, and the correct paths should all just flow through correctly.

There may be other issues with the new cmake configuration with generating for visual studio, but this should no longer be one of them. Closing for now, create any new issues against the new cmake bulid system. Thanks for the report!

@kdt3rd kdt3rd closed this as completed Jul 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Discussion To be discussed in the technical steering committee
Projects
None yet
Development

No branches or pull requests

4 participants