Windows: Can't link a project to OpenEXR that was built with static zlib
ignus2 opened this issue · 16 comments
Branch: master (f04fcdd)
Trying to use a Windows build of OpenEXR built with built-in zlib fails at first with the following error at CMake time:
Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
...
... /openexr/lib/cmake/OpenEXR/OpenEXRConfig.cmake:31 (find_dependency)
This is due to find_dependency(ZLIB REQUIRED) in OpenEXRConfig.cmake:31.
If I manually comment out that line, CMake succeeds, but now I get a linker error:
LINK : fatal error LNK1181: cannot open input file 'zlib_static.lib'
This is due to zlib_static being present in the INTERFACE_LINK_LIBRARIES of OpenEXR::OpenEXR
If I also manually remove zlib_static (from OpenEXRTargets.cmake) then my program all builds and runs fine.
I believe if OpenEXR is built with internal static zlib library, then zlib should not appear as a dependency and neither at the interface link libraries.
Can you provide the command line you are using for the cmake generation step?
In empty build dir, openexr one level up:
cmake ..\openexr -DCMAKE_INSTALL_PREFIX=..\install
cmake --build . --config Release --target Install
Ok, I removed zlib from my path, and I can reproduce the problem.
CMake Error at cmake/OpenEXRSetup.cmake:241 (add_library):
add_library cannot create ALIAS target "ZLIB::ZLIB" because target
"zlib_static" is imported but not globally visible.
Here's a fix, could you try it out?
diff --git a/cmake/OpenEXRSetup.cmake b/cmake/OpenEXRSetup.cmake
index 02dd4c5e..0b1049a9 100644
--- a/cmake/OpenEXRSetup.cmake
+++ b/cmake/OpenEXRSetup.cmake
@@ -228,7 +228,7 @@ if(OPENEXR_FORCE_INTERNAL_ZLIB OR NOT ZLIB_FOUND)
target_include_directories(zlib_shared INTERFACE "${zlib_INTERNAL_DIR}/include")
endif()
- add_library(zlib_static STATIC IMPORTED)
+ add_library(zlib_static STATIC IMPORTED GLOBAL)
add_dependencies(zlib_static zlib_external)
set_property(TARGET zlib_static PROPERTY
IMPORTED_LOCATION "${zlib_INTERNAL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}${zlibstaticlibname}${CMAKE_STATIC_LIBRARY_SUFFIX}"
It made no difference (should it have?, did it work for you?), resulting OpenEXRConfig.cmake and OpenEXRTargets.cmake ended up being the same.
However using this change did:
diff --git a/src/lib/OpenEXR/CMakeLists.txt b/src/lib/OpenEXR/CMakeLists.txt
index 64797f67..0775daac 100644
--- a/src/lib/OpenEXR/CMakeLists.txt
+++ b/src/lib/OpenEXR/CMakeLists.txt
@@ -189,5 +189,6 @@ openexr_define_library(OpenEXR
OpenEXR::Iex
OpenEXR::IlmThread
Imath::Imath
+ PRIVATE_DEPS
ZLIB::ZLIB
)
But it only removed the zlib_static from the INTERFACE_LINK_LIBRARIES of the OpenEXR::OpenEXR target in OpenEXRTargets.cmake.
The find_dependency(ZLIB REQUIRED) still remained in OpenEXRConfig.cmake, and that also needs to be removed.
Unfortunately this change is not suitable, as it must only be used as a PRIVATE_DEPS if zlib was built internally, not otherwise (I think?).
EDIT:
BTW, I don't get this error at all:
CMake Error at cmake/OpenEXRSetup.cmake:241 (add_library):
add_library cannot create ALIAS target "ZLIB::ZLIB" because target
"zlib_static" is imported but not globally visible.
OpenEXR builds fine as it is, it is only when I try to use it that I have the issues.
CMake version I use is 3.18.1.
It seems you have an older CMake, one before 3.18, which introduced the ALIAS_GLOBAL property, and since it is possible to alias non-global imported targets. https://cmake.org/cmake/help/v3.18/prop_tgt/ALIAS_GLOBAL.html
So that'll fix your issue (either that or the GLOBAL option you mentioned).
But the original issue remains. To clarify the title: I successfully built OpenEXR on Windows using it's internal static zlib. Using this build in my own project fails (as detailed in the original post).
Ok, thanks for the extra investigation. Yes, I built with CMake 3.17. I'll update my cmake and try again.
Hi, I have this same issue. Would it be possible to provide the steps required in order to get this to build please? @meshula did you make any progress with this?
My version of cmake is 3.19.2.
@Camuvingian Not yet. I gathered the related issues and related them to this one.
using internal zlib is an externally controllable variable, OPENEXR_FORCE_INTERNAL_ZLIB, can you let us know if that helps resolve your issue?
I have the same problem with CMake 3.18.0 on Windows, using MSVC 2019 and the latest OpenEXR release (3.1.2).
In my project, I link to OpenEXR as follows:
find_package(OpenEXR 3.1.2 REQUIRED)
target_link_libraries(${MODULE_TARGET} PRIVATE OpenEXR::OpenEXR)
My project source code compiles fine, but the linker complains with LNK1104: cannot open file 'zlib_static.lib'.
Neither the GLOBAL directive nor OPENEXR_FORCE_INTERNAL_ZLIB
solve the problem.
I also noticed that when building OpenEXR in Debug mode, the subprojects actually link to the Release version of zlib, so the Debug build fails if you haven't already built in Release.
How come nobody has had the same problem? OpenEXR is unlinkable from other projects.
The issue sounds like zlib_static is not being propagated as a link dependency. If this is broken, it should have been caught by CI, but perhaps we are not testing the OpenEXR static configuration on Windows? @xlietz, do you know the current status of the build matrix?
The issue sounds like zlib_static is not being propagated as a link dependency. If this is broken, it should have been caught by CI, but perhaps we are not testing the OpenEXR static configuration on Windows? @xlietz, do you know the current status of the build matrix?
The CI is building the Windows Release static and shared configurations in the Windows build matrix. Both of these Release builds build zlib internally (generates zlibstatic.lib, no underscore) according to the logs. IIRC there were issues with the Debug CI related to not being able to download the Boost lib every CI run. We should discuss this in the next TSC meeting.
Thanks for checking! The underscore/no underscore business is concerning.
We ran into the same issue while using OpenEXR as a third-party library for OpenCV. It seems that OpenEXR's dependency to zlib adds a reference to zlib_static.lib
. Here, not only the underscore is wrong (i.e. zlibstatic.lib
is correct) but also the path is missing. We think that this has to be fixed during the generation of OpenEXRTargets.cmake
inside lib\cmake\OpenEXR
of the respective installation directory.