Linking issues on Windows
KelSolaar opened this issue · comments
Hello,
I'm trying to build OpenImageIO with Ptex support and I'm having linking issues:
ptexinput.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl Ptex::v2_3::String::~String(void)" (__imp_??1String@v2_3@Ptex@@QEAA@XZ) referenced in function "public: virtual bool __cdecl OpenImageIO_v2_2::PtexInput::open(class std::basic_string<char,struct std::char_traits<char>
,class std::allocator<char> > const &,class OpenImageIO_v2_2::ImageSpec &)" (?open@PtexInput@OpenImageIO_v2_2@@UEAA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEAVImageSpec@2@@Z) [...\openimageio\build\platform-windows\arch-AMD64\msvc-19.1\python-3.7\qt-5.15.
2.rf1\oiio\src\libOpenImageIO\OpenImageIO.vcxproj]
ptexinput.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class Ptex::v2_3::PtexTexture * __cdecl Ptex::v2_3::PtexTexture::open(char const *,class Ptex::v2_3::String &,bool)" (__imp_?open@PtexTexture@v2_3@Ptex@@SAPEAV123@PEBDAEAVString@23@_N@Z) referenced in function "public:
virtual bool __cdecl OpenImageIO_v2_2::PtexInput::open(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class OpenImageIO_v2_2::ImageSpec &)" (?open@PtexInput@OpenImageIO_v2_2@@UEAA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEAVImageSpec@2@@Z
) [...\openimageio\build\platform-windows\arch-AMD64\msvc-19.1\python-3.7\qt-5.15.2.rf1\oiio\src\libOpenImageIO\OpenImageIO.vcxproj]
...\openimageio\build\platform-windows\arch-AMD64\msvc-19.1\python-3.7\qt-5.15.2.rf1\oiio\bin\Release\OpenImageIO.dll : fatal error LNK1120: 2 unresolved externals [...\openimageio\build\platform-windows\arch-AMD64\msvc-19.1\python-3.7\qt-5.15.2.rf1\
oiio\src\libOpenImageIO\OpenImageIO.vcxproj]
I looked at the exported symbols in my built Ptex.dll and there are small differences between what OpenImagIO is looking for and what is being exported:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC>dumpbin /exports H:\Documents\Development\ThirdParty\Ptex\build\platform-windows\arch-AMD64\msvc-19.1\release\lib\Ptex.dll
Microsoft (R) COFF/PE Dumper Version 14.00.24245.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file H:\Documents\Development\ThirdParty\Ptex\build\platform-windows\arch-AMD64\msvc-19.1\release\lib\Ptex.dll
File Type: DLL
Section contains the following exports for Ptex.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
19 number of functions
19 number of names
ordinal hint RVA name
1 0 0001E030 ??1String@v2_3@Ptex@@QEAA@XZ
2 1 0001E040 ??4String@v2_3@Ptex@@QEAAAEAV012@PEBD@Z
3 2 0001E640 ?BorderModeName@v2_3@Ptex@@YAPEBDW4BorderMode@12@@Z
4 3 0001E660 ?ConvertFromFloat@v2_3@Ptex@@YAXPEAXPEBMW4DataType@12@H@Z
5 4 0001E960 ?ConvertToFloat@v2_3@Ptex@@YAXPEAMPEBXW4DataType@12@H@Z
6 5 0001EAD0 ?DataTypeName@v2_3@Ptex@@YAPEBDW4DataType@12@@Z
7 6 0001EAF0 ?EdgeFilterModeName@v2_3@Ptex@@YAPEBDW4EdgeFilterMode@12@@Z
8 7 0001EB10 ?EdgeIdName@v2_3@Ptex@@YAPEBDW4EdgeId@12@@Z
9 8 0001EB30 ?MeshTypeName@v2_3@Ptex@@YAPEBDW4MeshType@12@@Z
10 9 0001EB50 ?MetaDataTypeName@v2_3@Ptex@@YAPEBDW4MetaDataType@12@@Z
11 A 00024B20 ?applyEdits@PtexWriter@v2_3@Ptex@@SA_NPEBDAEAVString@23@@Z
12 B 00001FC0 ?create@PtexCache@v2_3@Ptex@@SAPEAV123@H_K_NPEAVPtexInputHandler@23@PEAVPtexErrorHandler@23@@Z
13 C 00025180 ?edit@PtexWriter@v2_3@Ptex@@SAPEAV123@PEBD_NW4MeshType@23@W4DataType@23@HHHAEAVString@23@1@Z
14 D 00077000 ?f2hTable@PtexHalf@v2_3@Ptex@@2PAGA
15 E 00004C80 ?fromFloat_except@PtexHalf@v2_3@Ptex@@CAGI@Z
16 F 00004920 ?getFilter@PtexFilter@v2_3@Ptex@@SAPEAV123@PEAVPtexTexture@23@AEBUOptions@123@@Z
17 10 00037000 ?h2fTable@PtexHalf@v2_3@Ptex@@2PAIA
18 11 0000AE80 ?open@PtexTexture@v2_3@Ptex@@SAPEAV123@PEBDAEAVString@23@_N@Z
19 12 00026CE0 ?open@PtexWriter@v2_3@Ptex@@SAPEAV123@PEBDW4MeshType@23@W4DataType@23@HHHAEAVString@23@_N@Z
Summary
46000 .data
3000 .pdata
B000 .rdata
1000 .reloc
1000 .rsrc
2B000 .text
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC>undname ??1String@v2_3@Ptex@@QEAA@XZ
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "??1String@v2_3@Ptex@@QEAA@XZ"
is :- "public: __cdecl Ptex::v2_3::String::~String(void) __ptr64"
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC>undname ?open@PtexTexture@v2_3@Ptex@@SAPEAV123@PEBDAEAVString@23@_N@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?open@PtexTexture@v2_3@Ptex@@SAPEAV123@PEBDAEAVString@23@_N@Z"
is :- "public: static class Ptex::v2_3::PtexTexture * __ptr64 __cdecl Ptex::v2_3::PtexTexture::open(char const * __ptr64,class Ptex::v2_3::String & __ptr64,bool)"
- OIIO:
public: __cdecl Ptex::v2_3::String::~String(void)
- Ptex:
public: __cdecl Ptex::v2_3::String::~String(void) __ptr64
- OIIO:
public: static class Ptex::v2_3::PtexTexture * __cdecl Ptex::v2_3::PtexTexture::open(char const *,class Ptex::v2_3::String &,bool)
- Ptex:
public: static class Ptex::v2_3::PtexTexture * __ptr64 __cdecl Ptex::v2_3::PtexTexture::open(char const * __ptr64,class Ptex::v2_3::String & __ptr64,bool)
As far as I can tell, the only difference is __ptr64
, I'm building everything for x64
and I'm unclear if it is an OIIO issue at this point or Ptex. Paging @lgritz just in case he has an idea!
Cheers,
Thomas
I'm in critical danger of stepping beyond my windows knowledge, but there are a few common gotchas that I would double check first:
- That you're not accidentally picking up a set of ptex .h files that don't exactly correspond to the ptex libraries you have? (Sometimes weird things happen if you inadvertently have two different Ptex versions installed.)
- One library is release, the other is debug? (I think MSVS actually changes ABI slightly between debug and release builds)
- Mismatch in some other MSVS compiler flags that are required to be the same across all compilation units? (That
__ptr64
that's found but not expected is very suspicious.)
Hi Larry/@lgritz,
Thanks for replying!
- I have only a single Ptex library that I built the same way I build OIIO and all the VFX Reference Platform on Windows.
- The
cmake
configuration always use this generator and toolset:-G "Visual Studio 15 2017 Win64" -T v141,host=x64
(I have a variant for Visual Studio 14 2015 Win64 but it is not used for OIIO) and it is build as follows:cmake --build . --config Release --target INSTALL
- For what its worth, I'm linking OIIO against OpenEXR and Imath just fine and the symbols have the
__ptr64
type:
undname ?rgb2hsv_d@Imath_2_5@@YA?AV?$Vec3@N@1@AEBV21@@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?rgb2hsv_d@Imath_2_5@@YA?AV?$Vec3@N@1@AEBV21@@Z"
is :- "class Imath_2_5::Vec3<double> __cdecl Imath_2_5::rgb2hsv_d(class Imath_2_5::Vec3<double> const & __ptr64)"
I too am having this issue, I was curious if you ended up finding anything. My only guess was that OIIO was somehow looking for static ptex even during shared lib linking because of the __declspec(dllimport)
prefix in the error and the following snippet in the Ptexture.h file
#if defined(_WIN32) || defined(_WINDOWS) || defined(_MSC_VER)
# ifndef PTEXAPI
# ifndef PTEX_STATIC
# ifdef PTEX_EXPORTS
# define PTEXAPI __declspec(dllexport)
# else
# define PTEXAPI __declspec(dllimport)
# endif
# else
# define PTEXAPI
# endif
# endif
#else
# ifndef PTEXAPI
# define PTEXAPI
# endif
# ifndef DOXYGEN
# define PTEX_USE_STDSTRING
# endif
#endif
But I could not find anything in my OIIO vcxprojs or cmake files to suggest that OIIO is looking for static so I am scratching my head on this as well.
EDIT:
Turns out USD solved this themselves (from their build_usd.py file)
# Ptex has a bug where the import library for the dynamic library and
# the static library both get the same name, Ptex.lib, and as a
# result one clobbers the other. We hack the appropriate CMake
# file to prevent that. Since we don't need the static library we'll
# rename that.
#
# In addition src\tests\CMakeLists.txt adds -DPTEX_STATIC to the
# compiler but links tests against the dynamic library, causing the
# links to fail. We patch the file to not add the -DPTEX_STATIC
PatchFile('src\\ptex\\CMakeLists.txt',
[("set_target_properties(Ptex_static PROPERTIES OUTPUT_NAME Ptex)",
"set_target_properties(Ptex_static PROPERTIES OUTPUT_NAME Ptexs)")])
PatchFile('src\\tests\\CMakeLists.txt',
[("add_definitions(-DPTEX_STATIC)",
"# add_definitions(-DPTEX_STATIC)")])
Updating those files fixed it for me
Oh, nice find! We don't actually use the static libs much, and Windows even less, so this is a blind spot for us on Linux where we have libPtex.so and libPtex.a that don't conflict.
We should probably add some notes to the README about the PTEX_BUILD_STATIC_LIBS
and PTEX_BUILD_SHARED_LIBS
controls that the build system supports. They both default to ON
, so disabling one and enabling another explicitly should be a way to fix the build without any build tweaks on Windows.
I'll leave this issue open since we should probably change this so that the static lib are output as libPtex-static.a
(aka Ptex-static.lib
). That should resolve this issue if I'm understanding this correctly. Does that sound about right?
Heads-up @sunyab ~ hopefully that'll simplify build_usd.py
too.
The DLLImport thing is sort of a red herring, it's only there to generate headers for things that link to the DLL and need to know about the class interfaces so the export decls get put on the functions during the build and the headers are generated with the import symbols.
Normally you build the shared and static libs by setting two targets in CMake with different names (not output names), one with static and one with shared linkage... it'll naturally put them in different output directories and use the add_library name as the base name. This is cleaner because it makes CMake auto-sort things into the right places vs trying to find where you buried the output name definition and it allows importing from the project using the shared or static name and having everything else automagically work.
See this -- it's supposed to be controlled with the output directory variables, then whatever wants to link to it uses that structure if it's not integrating with the project CMakeFiles or selects shared vs. static linkage using the variables cmake creates in its caches (see this).