[FFmpeg-devel] [PATCH] Add Windows resource file support for shared libraries

James Almer jamrial at gmail.com
Mon Nov 25 23:06:30 CET 2013


On 25/11/13 6:59 PM, Timothy Gu wrote:
> Based on patch by: James Almer <jamrial at gmail.com>
> 
> Signed-off-by: Timothy Gu <timothygu99 at gmail.com>
> ---
> 
> Sorry if the older patch in the thread doesn't apply.
> 
> ---
> 
> Differences from James's version [1]:
> * Now generate the .rc files from configure (like we do with pkg-config files).

I'm not sure about this. They don't get installed, and having one .rc file per 
folder won't bother anyone, whereas the big generator function in configure will 
be a small nuisance with merges from libav.
x264 and mplayer ship with the .rc files in the source tree and don't generate them
either.

> * Use descriptions of libraries from the pkg-config file generation function
> * Use "FFmpeg Project" as CompanyName like Alexander suggested in the old thread
> * Use "FFmpeg" for ProductName as MSDN says "name of the product with which the
>   file is distributed" [2].
> * Use FFmpeg's version (N-xxxxx-gxxxxxxx) for ProductVersion per MSDN [2].
> 
> [1] http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2012-September/131705.html
> [2] http://msdn.microsoft.com/en-us/library/windows/desktop/aa381058.aspx

I'm fine with the changes.
Afterwards we should try to extend this to also cover the executables, like Gianluigi Tiesi 
did on his repo.

Some comments below.

> 
> ---
>  .gitignore             |  1 +
>  Makefile               |  3 ++-
>  common.mak             |  9 +++++--
>  configure              | 65 +++++++++++++++++++++++++++++++++++++++++++++++++-
>  libavcodec/Makefile    |  3 +++
>  libavdevice/Makefile   |  3 +++
>  libavfilter/Makefile   |  3 +++
>  libavformat/Makefile   |  3 +++
>  libavresample/Makefile |  3 +++
>  libavutil/Makefile     |  3 +++
>  libpostproc/Makefile   |  3 +++
>  library.mak            |  2 +-
>  libswresample/Makefile |  3 +++
>  libswscale/Makefile    |  3 +++
>  14 files changed, 102 insertions(+), 5 deletions(-)
> 
> diff --git a/.gitignore b/.gitignore
> index 7d8adda..8a63efc 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -13,6 +13,7 @@
>  *.lib
>  *.pc
>  *.pdb
> +*.rc
>  *.so
>  *.so.*
>  *.ver
> diff --git a/Makefile b/Makefile
> index 10202d0..53b8841 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -6,6 +6,7 @@ vpath %.cpp  $(SRC_PATH)
>  vpath %.h    $(SRC_PATH)
>  vpath %.S    $(SRC_PATH)
>  vpath %.asm  $(SRC_PATH)
> +vpath %.rc   $(SRC_PATH)
>  vpath %.v    $(SRC_PATH)
>  vpath %.texi $(SRC_PATH)
>  vpath %/fate_config.sh.template $(SRC_PATH)
> @@ -74,7 +75,7 @@ SUBDIR_VARS := CLEANFILES EXAMPLES FFLIBS HOSTPROGS TESTPROGS TOOLS      \
>                 ALTIVEC-OBJS VIS-OBJS                                     \
>                 MMX-OBJS YASM-OBJS                                        \
>                 MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS MIPS32R2-OBJS  \
> -               OBJS HOSTOBJS TESTOBJS
> +               OBJS SLIBOBJS HOSTOBJS TESTOBJS
>  
>  define RESET
>  $(1) :=
> diff --git a/common.mak b/common.mak
> index b22badd..0ddaaa5 100644
> --- a/common.mak
> +++ b/common.mak
> @@ -10,7 +10,7 @@ ifndef SUBDIR
>  ifndef V
>  Q      = @
>  ECHO   = printf "$(1)\t%s\n" $(2)
> -BRIEF  = CC CXX HOSTCC HOSTLD AS YASM AR LD STRIP CP
> +BRIEF  = CC CXX HOSTCC HOSTLD AS YASM AR LD STRIP CP WINDRES
>  SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM
>  
>  MSG    = $@
> @@ -56,6 +56,9 @@ COMPILE_S = $(call COMPILE,AS)
>  %.o: %.S
>  	$(COMPILE_S)
>  
> +%.o: %.rc
> +	$(WINDRES) $(IFLAGS) -o $@ $<
> +
>  %.i: %.c
>  	$(CC) $(CCFLAGS) $(CC_E) $<
>  
> @@ -82,6 +85,7 @@ endif
>  include $(SRC_PATH)/arch.mak
>  
>  OBJS      += $(OBJS-yes)
> +SLIBOBJS  += $(SLIBOBJS-yes)
>  FFLIBS    := $(FFLIBS-yes) $(FFLIBS)
>  TESTPROGS += $(TESTPROGS-yes)
>  
> @@ -90,6 +94,7 @@ FFEXTRALIBS := $(LDLIBS:%=$(LD_LIB)) $(EXTRALIBS)
>  
>  EXAMPLES  := $(EXAMPLES:%=$(SUBDIR)%-example$(EXESUF))
>  OBJS      := $(sort $(OBJS:%=$(SUBDIR)%))
> +SLIBOBJS  := $(sort $(SLIBOBJS:%=$(SUBDIR)%))
>  TESTOBJS  := $(TESTOBJS:%=$(SUBDIR)%) $(TESTPROGS:%=$(SUBDIR)%-test.o)
>  TESTPROGS := $(TESTPROGS:%=$(SUBDIR)%-test$(EXESUF))
>  HOSTOBJS  := $(HOSTPROGS:%=$(SUBDIR)%.o)
> @@ -127,7 +132,7 @@ $(TOOLOBJS): | tools
>  OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(TESTOBJS))
>  
>  CLEANSUFFIXES     = *.d *.o *~ *.h.c *.map *.ver *.ho *.gcno *.gcda
> -DISTCLEANSUFFIXES = *.pc
> +DISTCLEANSUFFIXES = *.pc *.rc
>  LIBSUFFIXES       = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a
>  
>  define RULES
> diff --git a/configure b/configure
> index 6b0375b..b334898 100755
> --- a/configure
> +++ b/configure
> @@ -267,6 +267,7 @@ Advanced options (experts only):
>    --nm=NM                  use nm tool NM [$nm_default]
>    --ar=AR                  use archive tool AR [$ar_default]
>    --as=AS                  use assembler AS [$as_default]
> +  --windres=WINDRES        use windows resource compiler WINDRES [$windres_default]
>    --yasmexe=EXE            use yasm-compatible assembler EXE [$yasmexe_default]
>    --cc=CC                  use C compiler CC [$cc_default]
>    --cxx=CXX                use C compiler CXX [$cxx_default]
> @@ -1478,6 +1479,7 @@ HAVE_LIST="
>      gettimeofday
>      glob
>      gnu_as
> +    gnu_windres
>      gsm_h
>      ibm_asm
>      inet_aton
> @@ -2325,6 +2327,7 @@ pkg_config_default=pkg-config
>  ranlib="ranlib"
>  strip_default="strip"
>  yasmexe_default="yasm"
> +windres_default="windres"
>  
>  nogas=":"
>  
> @@ -2594,6 +2597,7 @@ nm_default="${cross_prefix}${nm_default}"
>  pkg_config_default="${cross_prefix}${pkg_config_default}"
>  ranlib="${cross_prefix}${ranlib}"
>  strip_default="${cross_prefix}${strip_default}"
> +windres_default="${cross_prefix}${windres_default}"
>  
>  sysinclude_default="${sysroot}/usr/include"
>  
> @@ -3112,7 +3116,7 @@ test -n "$cc_type" && enable $cc_type ||
>  : ${dep_cc_default:=$cc}
>  : ${ld_default:=$cc}
>  : ${host_ld_default:=$host_cc}
> -set_default ar as dep_cc ld host_ld
> +set_default ar as dep_cc ld host_ld windres
>  
>  probe_cc as "$as"
>  asflags_filter=$_flags_filter
> @@ -3594,6 +3598,7 @@ case $target_os in
>          elif enabled arm; then
>              LIBTARGET=arm-wince
>          fi
> +        enabled shared && check_cmd $windres --version && enable gnu_windres
>          check_ldflags -Wl,--nxcompat
>          check_ldflags -Wl,--dynamicbase
>          shlibdir_default="$bindir_default"
> @@ -3656,6 +3661,7 @@ case $target_os in
>          SHFLAGS='-shared -Wl,--out-implib,$(SUBDIR)lib$(FULLNAME).dll.a'
>          objformat="win32"
>          enable dos_paths
> +        enabled shared && check_cmd $windres --version && enable gnu_windres
>          ;;
>      *-dos|freedos|opendos)
>          network_extralibs="-lsocket"
> @@ -4831,6 +4837,7 @@ LD_O=$LD_O
>  LD_LIB=$LD_LIB
>  LD_PATH=$LD_PATH
>  DLLTOOL=$dlltool
> +WINDRES=$windres
>  LDFLAGS=$LDFLAGS
>  SHFLAGS=$(echo $($ldflags_filter $SHFLAGS))
>  YASMFLAGS=$YASMFLAGS
> @@ -4916,6 +4923,7 @@ cat > $TMPH <<EOF
>  #define av_restrict $_restrict
>  #define EXTERN_PREFIX "${extern_prefix}"
>  #define EXTERN_ASM ${extern_prefix}
> +#define BUILDSUF "$build_suffix"
>  #define SLIBSUF "$SLIBSUF"
>  #define HAVE_MMX2 HAVE_MMXEXT
>  EOF
> @@ -5016,6 +5024,51 @@ Cflags: -I\${includedir}
>  EOF
>  }
>  
> +windres_generate(){
> +    enabled gnu_windres || return 0
> +    name=$1
> +    shortname=${name#lib}
> +    comment=$2
> +    capname=`echo $name | awk '{print toupper($0)}'`
> +    version=${capname}_VERSION
> +    enabled ${name#lib} || return 0
> +    mkdir -p $name
> +    cat <<EOF > $name/${shortname}res.rc
> +#include <windows.h>
> +#include "$name/version.h"
> +#include "../version.h"
> +#include "config.h"
> +
> +1 VERSIONINFO
> +FILEVERSION     ${version}_MAJOR, ${version}_MINOR, ${version}_MICRO, 0
> +PRODUCTVERSION  ${version}_MAJOR, ${version}_MINOR, ${version}_MICRO, 0
> +FILEFLAGSMASK   VS_FFI_FILEFLAGSMASK
> +FILEOS          VOS_NT_WINDOWS32
> +FILETYPE        VFT_DLL
> +{
> +    BLOCK "StringFileInfo"
> +    {
> +        BLOCK "040904E4"

040904B0 might be better (04B0 = Unicode, 04E4 = multilingual).

> +        {
> +            VALUE "CompanyName",      "FFmpeg Project"
> +            VALUE "FileDescription",  "$comment"
> +            VALUE "FileVersion",      AV_STRINGIFY($version)
> +            VALUE "InternalName",     "$name"
> +            VALUE "LegalCopyright",   "Copyright (C) 2000-2013 FFmpeg Project"

This is the one thing that left me unsatisfied back when i first wrote this patch.
It would be nice if 2013 could be replaced with a variable to avoid having to update 
it every year.
Maybe moving "const int this_year = 2013;" from cmdutils.c to some header, changing 
it into a define and including it from the .rc files.

> +            VALUE "OriginalFilename", "$shortname" BUILDSUF "-" AV_STRINGIFY(${version}_MAJOR) SLIBSUF
> +            VALUE "ProductName",      "FFmpeg"
> +            VALUE "ProductVersion",   FFMPEG_VERSION
> +        }
> +    }
> +
> +    BLOCK "VarFileInfo"
> +    {
> +        VALUE "Translation", 0x0409, 0x04E4

Same as above

> +    }
> +}
> +EOF
> +}
> +
>  lavfi_libs="libavutil${build_suffix} = $LIBAVUTIL_VERSION"
>  enabled libavfilter_deps_avcodec    && prepend lavfi_libs "libavcodec${build_suffix} = $LIBAVCODEC_VERSION,"
>  enabled libavfilter_deps_avformat   && prepend lavfi_libs "libavformat${build_suffix} = $LIBAVFORMAT_VERSION,"
> @@ -5038,6 +5091,16 @@ pkgconfig_generate libavresample "Libav audio resampling library"       "$LIBAVR
>  pkgconfig_generate libswscale    "FFmpeg image rescaling library"       "$LIBSWSCALE_VERSION"    "$LIBM"      "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
>  pkgconfig_generate libswresample "FFmpeg audio resampling library"      "$LIBSWRESAMPLE_VERSION" "$LIBM"      "libavutil${build_suffix} = $LIBAVUTIL_VERSION"
>  
> +windres_generate libavutil     "FFmpeg utility library"
> +windres_generate libavcodec    "FFmpeg codec library"
> +windres_generate libavformat   "FFmpeg container format library"
> +windres_generate libavdevice   "FFmpeg device handling library"
> +windres_generate libavfilter   "FFmpeg audio/video filtering library"
> +windres_generate libpostproc   "FFmpeg postprocessing library"
> +windres_generate libavresample "Libav audio resampling library"
> +windres_generate libswscale    "FFmpeg image rescaling library"
> +windres_generate libswresample "FFmpeg audio resampling library"
> +
>  fix_ffmpeg_remote(){
>      git_remote_from=$1
>      git_remote_to=$2
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index e8c1c1b..b0a5774 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -812,6 +812,9 @@ OBJS-$(HAVE_OS2THREADS)                += pthread.o pthread_slice.o pthread_fram
>  
>  OBJS-$(CONFIG_FRAME_THREAD_ENCODER)    += frame_thread_encoder.o
>  
> +# Windows resource file
> +SLIBOBJS-$(HAVE_GNU_WINDRES)           += avcodecres.o
> +
>  SKIPHEADERS                            += %_tablegen.h                  \
>                                            %_tables.h                    \
>                                            aac_tablegen_decl.h           \
> diff --git a/libavdevice/Makefile b/libavdevice/Makefile
> index 21ca954..9eb3d3b 100644
> --- a/libavdevice/Makefile
> +++ b/libavdevice/Makefile
> @@ -51,6 +51,9 @@ OBJS-$(CONFIG_XV_OUTDEV)                 += xv.o
>  OBJS-$(CONFIG_LIBCDIO_INDEV)             += libcdio.o
>  OBJS-$(CONFIG_LIBDC1394_INDEV)           += libdc1394.o
>  
> +# Windows resource file
> +SLIBOBJS-$(HAVE_GNU_WINDRES)             += avdeviceres.o
> +
>  SKIPHEADERS-$(CONFIG_DSHOW_INDEV)        += dshow_capture.h
>  SKIPHEADERS-$(CONFIG_LIBPULSE)           += pulse_audio_common.h
>  SKIPHEADERS-$(CONFIG_V4L2_INDEV)         += v4l2-common.h
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 7bd4323..12d803a 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -249,6 +249,9 @@ OBJS-$(CONFIG_SHOWWAVES_FILTER)              += avf_showwaves.o
>  OBJS-$(CONFIG_AMOVIE_FILTER)                 += src_movie.o
>  OBJS-$(CONFIG_MOVIE_FILTER)                  += src_movie.o
>  
> +# Windows resource file
> +SLIBOBJS-$(HAVE_GNU_WINDRES)                 += avfilterres.o
> +
>  SKIPHEADERS-$(CONFIG_LIBVIDSTAB)             += vidstabutils.h
>  SKIPHEADERS-$(CONFIG_OPENCL)                 += opencl_internal.h deshake_opencl_kernel.h unsharp_opencl_kernel.h
>  
> diff --git a/libavformat/Makefile b/libavformat/Makefile
> index b08ce57..609c00f 100644
> --- a/libavformat/Makefile
> +++ b/libavformat/Makefile
> @@ -463,6 +463,9 @@ OBJS-$(CONFIG_TLS_PROTOCOL)              += tls.o
>  OBJS-$(CONFIG_UDP_PROTOCOL)              += udp.o
>  OBJS-$(CONFIG_UNIX_PROTOCOL)             += unix.o
>  
> +# Windows resource file
> +SLIBOBJS-$(HAVE_GNU_WINDRES)             += avformatres.o
> +
>  SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
>  SKIPHEADERS-$(CONFIG_NETWORK)            += network.h rtsp.h
>  TESTPROGS = seek                                                        \
> diff --git a/libavresample/Makefile b/libavresample/Makefile
> index 6805280..bca23a9 100644
> --- a/libavresample/Makefile
> +++ b/libavresample/Makefile
> @@ -13,4 +13,7 @@ OBJS = audio_convert.o                                                  \
>         resample.o                                                       \
>         utils.o                                                          \
>  
> +# Windows resource file
> +SLIBOBJS-$(HAVE_GNU_WINDRES) += avresampleres.o
> +
>  TESTPROGS = avresample
> diff --git a/libavutil/Makefile b/libavutil/Makefile
> index 02dd728..9153818 100644
> --- a/libavutil/Makefile
> +++ b/libavutil/Makefile
> @@ -121,6 +121,9 @@ OBJS-$(CONFIG_OPENCL)                   += opencl.o opencl_internal.o
>  
>  OBJS += $(COMPAT_OBJS:%=../compat/%)
>  
> +# Windows resource file
> +SLIBOBJS-$(HAVE_GNU_WINDRES)            += avutilres.o
> +
>  SKIPHEADERS          = old_pix_fmts.h
>  
>  SKIPHEADERS-$(HAVE_ATOMICS_GCC)        += atomic_gcc.h
> diff --git a/libpostproc/Makefile b/libpostproc/Makefile
> index 3fb5a70..b9bb4be 100644
> --- a/libpostproc/Makefile
> +++ b/libpostproc/Makefile
> @@ -7,3 +7,6 @@ HEADERS = postprocess.h        \
>            version.h            \
>  
>  OBJS = postprocess.o
> +
> +# Windows resource file
> +SLIBOBJS-$(HAVE_GNU_WINDRES) += postprocres.o
> diff --git a/library.mak b/library.mak
> index e48aba1..fe06057 100644
> --- a/library.mak
> +++ b/library.mak
> @@ -51,7 +51,7 @@ $(EXAMPLES) $(TESTPROGS) $(TOOLS): %$(EXESUF): %.o $(EXEOBJS)
>  $(SUBDIR)$(SLIBNAME): $(SUBDIR)$(SLIBNAME_WITH_MAJOR)
>  	$(Q)cd ./$(SUBDIR) && $(LN_S) $(SLIBNAME_WITH_MAJOR) $(SLIBNAME)
>  
> -$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SUBDIR)lib$(NAME).ver
> +$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SLIBOBJS) $(SUBDIR)lib$(NAME).ver
>  	$(SLIB_CREATE_DEF_CMD)
>  	$$(LD) $(SHFLAGS) $(LDFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS)
>  	$(SLIB_EXTRA_CMD)
> diff --git a/libswresample/Makefile b/libswresample/Makefile
> index 0b75bd0..953c945 100644
> --- a/libswresample/Makefile
> +++ b/libswresample/Makefile
> @@ -15,4 +15,7 @@ OBJS = audioconvert.o                        \
>  OBJS-$(CONFIG_LIBSOXR) += soxr_resample.o
>  OBJS-$(CONFIG_SHARED)  += log2_tab.o
>  
> +# Windows resource file
> +SLIBOBJS-$(HAVE_GNU_WINDRES) += swresampleres.o
> +
>  TESTPROGS = swresample
> diff --git a/libswscale/Makefile b/libswscale/Makefile
> index dd00f7d..ca6e27d 100644
> --- a/libswscale/Makefile
> +++ b/libswscale/Makefile
> @@ -15,5 +15,8 @@ OBJS = input.o                                          \
>         utils.o                                          \
>         yuv2rgb.o                                        \
>  
> +# Windows resource file
> +SLIBOBJS-$(HAVE_GNU_WINDRES) += swscaleres.o
> +
>  TESTPROGS = colorspace                                                  \
>              swscale                                                     \
> 


More information about the ffmpeg-devel mailing list