Ticket #2049 (closed defect: fixed)
msvc: --extra-cflags="-MD" leads to unresolved externals
| Reported by: | Piroxiljin | Owned by: | |
|---|---|---|---|
| Priority: | normal | Component: | build system |
| Version: | git-master | Keywords: | msvc |
| Cc: | Blocked By: | ||
| Blocking: | Reproduced by developer: | no | |
| Analyzed by developer: | no |
Description
Summary of the bug:
Compilation ffmpeg with toolchain=msvc leads to unresolved external simbols.
How to reproduce:
I use guide from this page: http://blogs.gnome.org/rbultje/2012/09/27/microsoft-visual-studio-support-in-ffmpeg-and-libav/
I.e.
- Open MSVC2010 command prompt
- Run mingw-msys shell
c:\mingw\msys\1.0\msys.bat
- configure ffmpeg
./configure --toolchain=msvc --extra-cflags="-MD"
Waiting, while configuration has done.
- make
At the end of building I have error messages:
LD ffmpeg_g.exe LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; us e /NODEFAULTLIB:library libavutil.a(opt.o) : error LNK2001: unresolved external symbol __imp__avpriv_snp rintf libavutil.a(pixdesc.o) : error LNK2001: unresolved external symbol __imp__avpriv _snprintf libavutil.a(samplefmt.o) : error LNK2001: unresolved external symbol __imp__avpr iv_snprintf ... ffmpeg.o : error LNK2019: unresolved external symbol __imp__avpriv_vsnprintf ref erenced in function _update_benchmark libavformat.a(aviobuf.o) : error LNK2001: unresolved external symbol __imp__avpr iv_vsnprintf libavformat.a(utils.o) : error LNK2001: unresolved external symbol __imp__avpriv _vsnprintf libavformat.a(rtpproto.o) : error LNK2001: unresolved external symbol __imp__avp riv_vsnprintf libavformat.a(rtmpproto.o) : error LNK2019: unresolved external symbol __imp__av priv_strtod referenced in function _rtmp_write_amf_data libavformat.a(sbgdec.o) : error LNK2001: unresolved external symbol __imp__avpri v_strtod libavutil.a(parseutils.o) : error LNK2001: unresolved external symbol __imp__avp riv_strtod libavutil.a(eval.o) : error LNK2001: unresolved external symbol __imp__avpriv_st rtod ffmpeg_g.exe : fatal error LNK1120: 3 unresolved externals make: *** [ffmpeg_g.exe] Error 1
Change History
comment:2 in reply to: ↑ 1 ; follow-up: ↓ 3 Changed 5 months ago by Piroxiljin
Replying to cehoyos:
Why do you want to add -MD to the compiler flags?
I use ffmpeg libraries, and my application and all other libraries are linked with DLL run-time library.
MSDN: /MD, /MT, /LD (Use Run-Time Library) ( http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=vs.100).aspx)
-MD Causes your application to use the multithread- and DLL-specific version of the run-time library.
-MT Causes your application to use the multithread, static version of the run-time library.
Also, I found out that prefix __imp__ appears when object-file compiles with -MD. In another way (without -MD, or with -MT) all unresolved symbols has another prefix.(I'm not sure, but I belive it just underscore. I'll check it tomorrow. ) And those object-files (and static libavutils.a) successfully linked with ffmpeg.exe
comment:3 in reply to: ↑ 2 ; follow-up: ↓ 4 Changed 5 months ago by cehoyos
Replying to Piroxiljin:
Replying to cehoyos:
Why do you want to add -MD to the compiler flags?
MSDN: /MD, /MT, /LD (Use Run-Time Library) ( http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=vs.100).aspx)
-MD Causes your application to use the multithread- and DLL-specific version of the run-time library.
I had also read that page today and please excuse my ignorance but are you sure that "/MD" is the same as "-MD"?
comment:4 in reply to: ↑ 3 Changed 5 months ago by Piroxiljin
Replying to cehoyos:
Replying to Piroxiljin:
Replying to cehoyos:
Why do you want to add -MD to the compiler flags?
MSDN: /MD, /MT, /LD (Use Run-Time Library) ( http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=vs.100).aspx)
-MD Causes your application to use the multithread- and DLL-specific version of the run-time library.
I had also read that page today and please excuse my ignorance but are you sure that "/MD" is the same as "-MD"?
Compiler Command-Line Syntax ( http://msdn.microsoft.com/en-us/library/610ecb4h(v=vs.100).aspx)
CL [option...] file... [option | file]... [lib...] [@command-file] [/link link-opt...]
option - One or more CL options. Note that all options apply to all specified source files. Options are specified by either a forward slash (/) or a dash (–). If an option takes an argument, the option's description documents whether a space is allowed between the option and the arguments. Option names (except for the /HELP option) are case sensitive. See Order of CL Options for more information.
Yes, I am.
comment:5 Changed 5 months ago by Piroxiljin
Well.
The source of the trouble is msvc preprocessor and declaration of funtions in standart library, when compiles with DLL runtime.
Compilation is evoked with command like this
c99wrap cl -I. -I./ -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ -Dstrtod=avpriv_strtod -Dsnprintf=avpriv_snprintf -D_snprintf=avpriv_snprintf \ -Dvsnprintf=avpriv_vsnprintf -DHAVE_AV_CONFIG_H -nologo -D_USE_MATH_DEFINES \ -Dinline=__inline -FIstdlib.h -Dstrtoll=_strtoi64 -Oy -Z7 -W4 -wd4244 \ -wd4127 -wd4018 -wd4389 -wd4146 -wd4057 -wd4204 -wd4706 -wd4305 -wd4152 \ -wd4324 -we4013 -wd4100 -wd4214 -wd4554 -wd4996 -wd4273 -O2 -MD -c \ -Fo libavutil/../compat/msvcrt/snprintf.o libavutil/../compat/msvcrt/snprintf.c
Here we have preprocessor defines which replace "snprintf" to "avpriv_snprintf"
Also, preprocessed source file includes declarations of _snprintf ( and another functions from standart library). When we compile with -MD option, this functions are declared as
#pragma warning(push)
#pragma warning(disable:4793)
__declspec(deprecated("This function or variable may be unsafe. Consider using " \
"_snprintf_s" " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.")) \
__declspec(dllimport) int __cdecl _snprintf( char *_Dest, size_t _Count, const char * _Format, ...);\
__declspec(deprecated("This function or variable may be unsafe. Consider using " "_vsnprintf_s" " instead. \
To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.")) \
__declspec(dllimport) int __cdecl _vsnprintf( char *_Dest, size_t _Count, const char * _Format, va_list _Args);
#pragma warning(pop)
I.e. this functions declared as imported from DLL.
But preprocessor replace such declarations and so we have our avpriv_snprintf function is declared as imported.
comment:7 Changed 5 months ago by cehoyos
Is it sufficient to just compile snprintf.c manually without the defines that cause the trouble or are the defines bad for all source files?
comment:8 Changed 5 months ago by Piroxiljin
In this way, you need to compile manualy every file which uses redefined functions.
Also, this page (http://ffmpeg.org/platform.html#Linking-to-FFmpeg-with-Microsoft-Visual-C_002b_002b) notifies that one must link project with static runtime (/MT option).
Right now, I just compile shared library with static runtime.
comment:9 Changed 5 months ago by reimar
Since we do not use _snprintf I don't understand why that define is there.
Could you try with this configure patch, if that makes all cases work:
--- a/configure
+++ b/configure
@@ -3372,7 +3372,6 @@ elif check_func_headers stdlib.h _get_doserrno; then
libc_type=msvcrt
add_compat strtod.o strtod=avpriv_strtod
add_compat msvcrt/snprintf.o snprintf=avpriv_snprintf \
- _snprintf=avpriv_snprintf \
vsnprintf=avpriv_vsnprintf
elif check_cpp_condition stddef.h "defined __KLIBC__"; then
libc_type=klibc
comment:10 Changed 5 months ago by Piroxiljin
$ make
echo @printf "CC\t%s\n" libavfilter/af_amix.o; c99wrap cl -I. -I./ -D_ISOC99_SOU
RCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Dstrtod=avpriv_strtod -Dsnprintf
=avpriv_snprintf -Dvsnprintf=avpriv_vsnprintf -DHAVE_AV_CONFIG_H -nologo -D_USE_
MATH_DEFINES -Dinline=__inline -FIstdlib.h -Dstrtoll=_strtoi64 -Z7 -MD -Oy -Z7
-W4 -wd4244 -wd4127 -wd4018 -wd4389 -wd4146 -wd4057 -wd4204 -wd4706 -wd4305 -wd4
152 -wd4324 -we4013 -wd4100 -wd4214 -wd4554 -wd4996 -wd4273 -O2 -c -Fo libav
filter/af_amix.o libavfilter/af_amix.c
@printf CC\t%s\n libavfilter/af_amix.o
af_amix.c
d:\user\Alex\projects\ffmpeg\msvc-10-debug\3\ffmpeg-HEAD-1166fc0\config.h(9) : w
arning C4005: 'av_restrict' : macro redefinition
d:\user\alex\projects\ffmpeg\msvc-10-debug\3\ffmpeg-head-1166fc0\libavut
il\attributes.h(66) : see previous definition of 'av_restrict'
af_amix.o_converted.c
libavfilter/af_amix.c(502) : error C4013: 'avpriv_snprintf' undefined; assuming
extern returning int
libavfilter/af_amix.c(531) : warning C4090: 'function' : different 'const' quali
fiers
make: *** [libavfilter/af_amix.o] Error 1
comment:11 Changed 3 weeks ago by cehoyos
- Status changed from open to closed
- Resolution set to fixed
Should be fixed by Martin Storsjö since 760f7d3, please test!
comment:12 Changed 2 weeks ago by Piroxiljin
Well.
./configure --toolchain=msvc --extra-cflags="-MD" make ffmpeg.exe
now produces executable, but
./configure --toolchain=msvc --extra-cflags="-MD" make
produces link error
HOSTLD doc/print_options.exe cl : Command line warning D9002 : ignoring unknown option '-lm' cl : Command line warning D9024 : unrecognized source file type 'doc/print_optio ns.o', object file assumed print_options.o : error LNK2001: unresolved external symbol _avpriv_strtod print_options.o : error LNK2001: unresolved external symbol _avpriv_snprintf doc/print_options.exe : fatal error LNK1120: 2 unresolved externals make: *** [doc/print_options.exe] Error 1
comment:13 Changed 2 weeks ago by cehoyos
Could you test the following?
$ make ffmpeg.exe
comment:14 Changed 2 weeks ago by Piroxiljin
make ffmpeg.exe
produces a lot of warnings, but linking is successful.
comment:15 Changed 2 weeks ago by cehoyos
Could you test again with git head?
comment:16 Changed 2 weeks ago by Piroxiljin
Great!
$ make
is done without errors!
comment:17 Changed 2 weeks ago by cehoyos
Thank you for testing again!



Why do you want to add -MD to the compiler flags?