#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.
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?