#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 (18)
follow-up: 2 comment:1 by , 12 years ago
follow-up: 3 comment:2 by , 12 years ago
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
follow-up: 4 comment:3 by , 12 years ago
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 by , 12 years ago
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 by , 12 years ago
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:6 by , 12 years ago
Status: | new → open |
---|
comment:7 by , 12 years ago
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 by , 12 years ago
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 by , 12 years ago
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 by , 12 years ago
$ 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 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | open → closed |
Should be fixed by Martin Storsjö since 760f7d3, please test!
comment:12 by , 12 years ago
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:18 by , 11 years ago
As I remember on old ffmpeg I have used workaround like:
libavtuil/common.h:
#if _MSC_VER
#define snprintf _snprintf
#endif
Why do you want to add -MD to the compiler flags?