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

Windows linker error LNK2019: unresolved external symbol __imp_avifGainMapMetadataDoubleToFractions referenced in function avifJPEGParseGainMapXMPProperties #2339

Closed
wantehchang opened this issue Jul 29, 2024 · 3 comments · Fixed by #2318
Assignees

Comments

@wantehchang
Copy link
Collaborator

wantehchang commented Jul 29, 2024

@jzern @maryla-uc @vrabaud

This is a strange linker error on Windows when doing a shared library build (-DBUILD_SHARED_LIBS=ON). I can only reproduce it when all experimental features are enabled.

To reproduce the linker error, run these commands:

mkdir build & cd build
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DAVIF_CODEC_AOM=LOCAL -DAVIF_CODEC_DAV1D=LOCAL -DAVIF_JPEG=LOCAL -DAVIF_LIBSHARPYUV=LOCAL -DAVIF_LIBYUV=LOCAL -DAVIF_ZLIBPNG=LOCAL -DAVIF_BUILD_EXAMPLES=ON -DAVIF_BUILD_APPS=ON -DAVIF_BUILD_TESTS=ON -DAVIF_ENABLE_GTEST=ON -DAVIF_GTEST=LOCAL -DAVIF_ENABLE_WERROR=ON -DAVIF_LIBXML2=LOCAL -DAVIF_ENABLE_EXPERIMENTAL_YCGCO_R=ON -DAVIF_ENABLE_EXPERIMENTAL_GAIN_MAP=ON -DAVIF_ENABLE_EXPERIMENTAL_METAV1=ON -DAVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM=ON
ninja

We get a linker error, with a lot of linker warnings before it, like the following, when linking some tests:

[29/58] Linking CXX executable tests\avifcolrtest.exe
FAILED: tests/avifcolrtest.exe
C:\WINDOWS\system32\cmd.exe /C "cd . && "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=tests\CMakeFiles\avifcolrtest.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x64\mt.exe --manifests  -- C:\PROGRA~1\MICROS~2\2022\COMMUN~1\VC\Tools\MSVC\1440~1.338\bin\Hostx64\x64\link.exe /nologo tests\CMakeFiles\aviftest_helpers_internal.dir\gtest\aviftest_helpers.cc.obj tests\CMakeFiles\avifcolrtest.dir\gtest\avifcolrtest.cc.obj  /out:tests\avifcolrtest.exe /implib:tests\avifcolrtest.lib /pdb:tests\avifcolrtest.pdb /version:0.0 /machine:x64 /INCREMENTAL:NO /subsystem:console  lib\gtest.lib  lib\gtest_main.lib  avif_apps_internal.lib  _deps\libpng\libpng16_static.lib  _deps\zlib\zlibstatic.lib  libjpeg\src\libjpeg-build\jpeg-static.lib  _deps\libxml2-build\libxml2s.lib  ws2_32.lib  avif_internal.lib  _deps\libyuv-build\yuv.lib  _deps\libwebp\libsharpyuv.lib  _deps\dav1d-install\lib\libdav1d.a  _deps\aom-build\aom.lib  _deps\libyuv-build\yuv.lib  lib\gtest.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
LINK: command "C:\PROGRA~1\MICROS~2\2022\COMMUN~1\VC\Tools\MSVC\1440~1.338\bin\Hostx64\x64\link.exe /nologo tests\CMakeFiles\aviftest_helpers_internal.dir\gtest\aviftest_helpers.cc.obj tests\CMakeFiles\avifcolrtest.dir\gtest\avifcolrtest.cc.obj /out:tests\avifcolrtest.exe /implib:tests\avifcolrtest.lib /pdb:tests\avifcolrtest.pdb /version:0.0 /machine:x64 /INCREMENTAL:NO /subsystem:console lib\gtest.lib lib\gtest_main.lib avif_apps_internal.lib _deps\libpng\libpng16_static.lib _deps\zlib\zlibstatic.lib libjpeg\src\libjpeg-build\jpeg-static.lib _deps\libxml2-build\libxml2s.lib ws2_32.lib avif_internal.lib _deps\libyuv-build\yuv.lib _deps\libwebp\libsharpyuv.lib _deps\dav1d-install\lib\libdav1d.a _deps\aom-build\aom.lib _deps\libyuv-build\yuv.lib lib\gtest.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST:EMBED,ID=1" failed (exit code 1120) with the following output:
   Creating library tests\avifcolrtest.lib and object tests\avifcolrtest.exp
LINK : warning LNK4217: symbol 'avifRWDataRealloc' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifCopyRawProfile'
LINK : warning LNK4286: symbol 'avifRWDataRealloc' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(avifutil.c.obj)'
LINK : warning LNK4286: symbol 'avifRWDataRealloc' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)'
LINK : warning LNK4286: symbol 'avifRWDataRealloc' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(y4m.c.obj)'
LINK : warning LNK4217: symbol 'avifRWDataSet' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifExtractExifAndXMP'
LINK : warning LNK4286: symbol 'avifRWDataSet' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(iccmaker.c.obj)'
LINK : warning LNK4286: symbol 'avifRWDataSet' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)'
LINK : warning LNK4217: symbol 'avifRWDataFree' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifCopyRawProfile'
LINK : warning LNK4286: symbol 'avifRWDataFree' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(avifutil.c.obj)'
LINK : warning LNK4286: symbol 'avifRWDataFree' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)'
LINK : warning LNK4286: symbol 'avifRWDataFree' defined in 'avif_internal.lib(rawdata.c.obj)' is imported by 'avif_apps_internal.lib(y4m.c.obj)'
LINK : warning LNK4217: symbol 'avifColorPrimariesGetValues' defined in 'avif_internal.lib(colr.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGRead'
LINK : warning LNK4217: symbol 'avifColorPrimariesFind' defined in 'avif_internal.lib(colr.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGRead'
LINK : warning LNK4217: symbol 'avifTransferCharacteristicsGetGamma' defined in 'avif_internal.lib(colr.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGWrite'
LINK : warning LNK4217: symbol 'avifTransferCharacteristicsFindByGamma' defined in 'avif_internal.lib(colr.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGRead'
LINK : warning LNK4217: symbol 'avifImageSetProfileICC' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGRead'
LINK : warning LNK4286: symbol 'avifImageSetProfileICC' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)'
LINK : warning LNK4217: symbol 'avifImageSetMetadataXMP' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifExtractExifAndXMP'
LINK : warning LNK4286: symbol 'avifImageSetMetadataXMP' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)'
LINK : warning LNK4217: symbol 'avifRGBImageSetDefaults' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGRead'
LINK : warning LNK4286: symbol 'avifRGBImageSetDefaults' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)'
LINK : warning LNK4217: symbol 'avifRGBImageAllocatePixels' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGRead'
LINK : warning LNK4286: symbol 'avifRGBImageAllocatePixels' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)'
LINK : warning LNK4217: symbol 'avifRGBImageFreePixels' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGRead'
LINK : warning LNK4286: symbol 'avifRGBImageFreePixels' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)'
LINK : warning LNK4217: symbol 'avifImageRGBToYUV' defined in 'avif_internal.lib(reformat.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGRead'
LINK : warning LNK4286: symbol 'avifImageRGBToYUV' defined in 'avif_internal.lib(reformat.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)'
LINK : warning LNK4217: symbol 'avifImageYUVToRGB' defined in 'avif_internal.lib(reformat.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGWrite'
LINK : warning LNK4286: symbol 'avifImageYUVToRGB' defined in 'avif_internal.lib(reformat.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)'
LINK : warning LNK4217: symbol 'avifImageIsOpaque' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifpng.c.obj)' in function 'avifPNGWrite'
LINK : warning LNK4217: symbol 'avifVersion' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifutil.c.obj)' in function 'avifPrintVersions'
LINK : warning LNK4217: symbol 'avifCodecVersions' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifutil.c.obj)' in function 'avifPrintVersions'
LINK : warning LNK4217: symbol 'avifLibYUVVersion' defined in 'avif_internal.lib(reformat_libyuv.c.obj)' is imported by 'avif_apps_internal.lib(avifutil.c.obj)' in function 'avifPrintVersions'
LINK : warning LNK4217: symbol 'avifPixelFormatToString' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifutil.c.obj)' in function 'avifImageDumpInternal'
LINK : warning LNK4217: symbol 'avifDiagnosticsClearError' defined in 'avif_internal.lib(diag.c.obj)' is imported by 'avif_apps_internal.lib(avifutil.c.obj)' in function 'avifImageDumpInternal'
LINK : warning LNK4217: symbol 'avifCropRectConvertCleanApertureBox' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifutil.c.obj)' in function 'avifImageDumpInternal'
LINK : warning LNK4217: symbol 'avifProgressiveStateToString' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifutil.c.obj)' in function 'avifImageDumpInternal'
LINK : warning LNK4217: symbol 'avifPeekCompatibleFileType' defined in 'avif_internal.lib(read.c.obj)' is imported by 'avif_apps_internal.lib(avifutil.c.obj)' in function 'avifGuessBufferFileFormat'
LINK : warning LNK4217: symbol 'avifGetExifOrientationOffset' defined in 'avif_internal.lib(exif.c.obj)' is imported by 'avif_apps_internal.lib(avifexif.c.obj)' in function 'avifSetExifOrientation'
LINK : warning LNK4217: symbol 'avifResultToString' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)' in function 'avifJPEGWrite'
LINK : warning LNK4286: symbol 'avifResultToString' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(y4m.c.obj)'
LINK : warning LNK4217: symbol 'avifGetExifTiffHeaderOffset' defined in 'avif_internal.lib(exif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)' in function 'avifJPEGWrite'
LINK : warning LNK4217: symbol 'avifGainMapCreate' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)' in function 'avifJPEGReadInternal'
LINK : warning LNK4217: symbol 'avifGainMapDestroy' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)' in function 'avifJPEGReadInternal'
LINK : warning LNK4217: symbol 'avifImageCreateEmpty' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)' in function 'avifJPEGExtractGainMapImage'
LINK : warning LNK4217: symbol 'avifImageDestroy' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)' in function 'avifJPEGExtractGainMapImage'
LINK : warning LNK4217: symbol 'avifImageSetMetadataExif' defined in 'avif_internal.lib(exif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)' in function 'avifJPEGReadInternal'
LINK : warning LNK4217: symbol 'avifImageAllocatePlanes' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)' in function 'avifJPEGCopyPixels'
LINK : warning LNK4286: symbol 'avifImageAllocatePlanes' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(y4m.c.obj)'
LINK : warning LNK4217: symbol 'avifImageFreePlanes' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)' in function 'avifJPEGCopyPixels'
LINK : warning LNK4286: symbol 'avifImageFreePlanes' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(y4m.c.obj)'
LINK : warning LNK4217: symbol 'avifImagePlaneHeight' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(avifjpeg.c.obj)' in function 'avifJPEGReadCopy'
LINK : warning LNK4286: symbol 'avifImagePlaneHeight' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(y4m.c.obj)'
LINK : warning LNK4217: symbol 'avifImageUsesU16' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(y4m.c.obj)' in function 'y4mClampSamples'
LINK : warning LNK4217: symbol 'avifImagePlane' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(y4m.c.obj)' in function 'y4mClampSamples'
LINK : warning LNK4217: symbol 'avifImagePlaneRowBytes' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(y4m.c.obj)' in function 'y4mClampSamples'
LINK : warning LNK4217: symbol 'avifImagePlaneWidth' defined in 'avif_internal.lib(avif.c.obj)' is imported by 'avif_apps_internal.lib(y4m.c.obj)' in function 'y4mClampSamples'
avif_apps_internal.lib(avifjpeg.c.obj) : error LNK2019: unresolved external symbol __imp_avifGainMapMetadataDoubleToFractions referenced in function avifJPEGParseGainMapXMPProperties
tests\avifcolrtest.exe : fatal error LNK1120: 1 unresolved externals
@wantehchang wantehchang self-assigned this Jul 29, 2024
@wantehchang
Copy link
Collaborator Author

This linker error is strange because all the linker warnings before it are the same problem but the linker somehow fixes them up and merely emits warnings. Also, the linker error is gone if I move the definitions of two gainmap-related functions from src/avif.c to src/gainmap.c, as I did in 4a4ff64. (I reverted that commit later because it would have required Chrome to build src/gainmap.c.)

I haven't figured out what is wrong. I am going to fix what the linker warns about: the source files in avif_apps_internal.lib should not be compiled with -DAVIF_DLL. That causes the unresolved symbol __imp_avifGainMapMetadataDoubleToFractions (note the __imp_ predix in the symbol name, caused by __declspec(dllimport) in the AVIF_API macro definition).

@wantehchang
Copy link
Collaborator Author

I found that only the gain map experimental feature needs to be enabled to reproduce the linker error:

cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DAVIF_CODEC_AOM=LOCAL -DAVIF_CODEC_DAV1D=LOCAL -DAVIF_JPEG=LOCAL -DAVIF_LIBSHARPYUV=LOCAL -DAVIF_LIBYUV=LOCAL -DAVIF_ZLIBPNG=LOCAL -DAVIF_BUILD_EXAMPLES=ON -DAVIF_BUILD_APPS=ON -DAVIF_BUILD_TESTS=ON -DAVIF_ENABLE_GTEST=ON -DAVIF_GTEST=LOCAL -DAVIF_ENABLE_WERROR=ON -DAVIF_LIBXML2=LOCAL -DAVIF_ENABLE_EXPERIMENTAL_GAIN_MAP=ON

wantehchang added a commit that referenced this issue Jul 30, 2024
Add a CI workflow for building shared libraries with local dependencies
on Windows. Run on merge only.

Enable experimental features except AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP.
When #2339 is fixed,
enable AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP.
wantehchang added a commit to wantehchang/libavif that referenced this issue Jul 30, 2024
In shared library builds (-DBUILD_SHARED_LIBS=ON), compile the source
files in the avif_apps_internal static library without -DAVIF_DLL.

Also link avif_obj with the m and Threads::Threads libraries in the
PRIVATE scope instead of the PUBLIC scope.

Fix AOMediaCodec#2339.
wantehchang added a commit to wantehchang/libavif that referenced this issue Jul 30, 2024
wantehchang added a commit to wantehchang/libavif that referenced this issue Jul 30, 2024
In shared library builds (-DBUILD_SHARED_LIBS=ON), compile the source
files in the avif_apps_internal static library without -DAVIF_DLL.

Also link avif_obj with the m and Threads::Threads libraries in the
PRIVATE scope instead of the PUBLIC scope.

Fix AOMediaCodec#2339.
wantehchang added a commit that referenced this issue Jul 31, 2024
In shared library builds (-DBUILD_SHARED_LIBS=ON), compile the source
files in the avif_apps_internal static library without -DAVIF_DLL.

Also link avif_obj with the m and Threads::Threads libraries in the
PRIVATE scope instead of the PUBLIC scope.

Fix #2339.
wantehchang added a commit to wantehchang/libavif that referenced this issue Jul 31, 2024
Enable AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP in ci-windows-shared-local.yml.
AOMediaCodec#2339 has been fixed.
wantehchang added a commit that referenced this issue Jul 31, 2024
Enable AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP in ci-windows-shared-local.yml.
#2339 has been fixed.
@wantehchang
Copy link
Collaborator Author

I verified on my Windows laptop that this is fixed by commit cde6fcd. Our new CI workflow ci-windows-shared-local.yml also verified this has been fixed.

I still don't know why only __imp_avifGainMapMetadataDoubleToFractions caused the unresolved symbol linker error, but if a correctly-built avif_apps_internal.lib fixed this linker error, I am happy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant