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.
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 3 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 3 weeks ago by cehoyos
Could you test the following?
$ make ffmpeg.exe
comment:14 Changed 3 weeks ago by Piroxiljin
make ffmpeg.exe
produces a lot of warnings, but linking is successful.
comment:15 Changed 3 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?