Open CrendKing opened 3 years ago
See #192 for the background on the static linking reasoning (and a GPL mini-discussion; I honestly don't know where I'm supposed to come down on that topic, as it sort of depends on whether a client program that calls in AviSynth itself is substantively different from plugins, which AFAICT is what the GPL linking exception was actually intended to cover). There's also a rather hacky example of what I did to make FFmpeg use a static build of it on Linux. FFmpeg, of course, uses the C API, not the C++ API.
Generally, I'd consider static linking an experimental feature, much like being able to build with MinGW-w64/GCC (which you can also do, even though using it seriously means you would have to either restrict yourself to using only C plugins, or use g++ to recompile every C++ plugin you use as well*).
*and a special build of FFmpeg with alternate --extra-cflags to talk to it if it's 32-bit. Regular 64-bit builds of FFmpeg are fine with GCC builds of AviSynth+.
Thanks for providing the PR link and ffmpeg example. As I understand,
Regarding #130, I think what I get is, if static linking is possible, the whole AVS_linkage issue would not happen because non-Windows users could simply static link avs+. Dynamic linking exists only to loose license requirement. But pylorak mentioned in the PR that "Unfortunate because Avisynth will never be able to change it. It has already tried, very aggressively even, but the task was impossible in the end." I guess the mechanism and dynamic linking has to stay (unless someone complete rewrites avs+ from scratch with non-GPL licensing :) )
OK. So the conclusion is, for non-GPL Windows MSVC C++ API users, static linking won't ever be not available, correct?
The binaries would be required to be distributed under the terms of the GPL if linked (but, you know, IANAL). Just look at FFMS2, for example:
The FFMS2 source is licensed under the MIT license, but its binaries
are licensed under the GPL because GPL components of FFmpeg are
used. FFmpeg can be built as either LGPL, GPLv2, GPLv3, or even be
nonredistributable. Refer to FFmpeg's sources for licensing information.
As far as I understand it, AVS_Linkage has nothing to do with license trickery, it's some sort of plaster over incompatibilities in AVISYNTH_INTERFACE_VERSION and its very potentially Windows-specific nature is more about keeping users of old plugins happy than anything else, or for program authors wishing to support incompatible AVISYNTH_INTERFACE_VERSIONs (read: 2.5 vs. 2.6) at the same time instead of simply tracking upstream and dropping support for the incompatible ones as the library evolves.
IANAL too. What does it mean by distributing binaries under GPL? Does that mean anything that loads FFMS2 as plugin and be distributed as a whole (e.g. a player that bundles FFMS2 binaries in its distributed form) must be under GPL, but if that player compiles FFMS2 from source and static link it with a non-GPL ffmpeg version it can be non-GPL?
About AVS_linkage. Yes, the interface version is also a main reason for AVS_linkage. But the whole AVS_linkage mechanism works because of dynamic linking. If I link avs+ statically, there is just the one interface version that I choose to support at the compile time. It sounds to be much cleaner than dealing with a version-feature matrix at runtime. I no longer need to worry if my program is loaded in a system where avs+ 3.5 or 4.0 is installed, which might be completely incompatible with my 3.6 tested code.
So I hacked a version of avs+ locally that is fully statically linked into my program. It works for sure, and my program size jumped from 500KB to 5MB (with /MT
runtime of course), which is approximately the whole size of the AviSynth.dll, which is expected.
To make it work, I basically made 3 changes:
AVS_STATIC_LIB
from CMake, which is defined only if the core is built static for backward compatibility. Then check the macro in capi.h and remove those __declspec(dllxxx)
if defined.AVS_BakedCode
and AVS_linkage
, which is currently checked by BUILDING_AVSCORE
. I add AVS_STATIC_LIB
with OR relation to it. So all those linkage stuff are undefined.DllMain()
. I need to extract the body of DllMain into methods that are exported in avisynth.h, and call those methods in my program the same way as how when a DLL is loaded, to setup the TLS.I don't know if you guys want these changes as a PR. Let me know.
Go ahead and open a PR, as that way it can be reviewed more in-depth.
Thanks for merging the PR. I suppose we still need to wait for pinterf to make the final decision on XP TLS support, right?
I dunno. I mean, we already have a -DWINXP_SUPPORT option in the CMake configuration, so shuffling the (de)activation of the XP_TLS
defines based on whether we're telling it to build with XP compatibility makes sense.
Seems logical to me. Want me to create an issue for tracking?
Also, just to confirm the last time: if anyone statically link Avs+ to their program and distribute, the program must be on GPL, period, right?
I see the 3.7.0 update has feature of "Support for building the core as a static library". I checked out the source and turned off
BUILD_SHARED_LIBS
. I can see a biggerAviSynth.lib
generated, but I have trouble linking it. Please help?__declspec(dllimport)
regardless. Thus, APIs withAVSC_API
such asCreateScriptEnvironment
cannot be resolved.__declspec(dllimport)
, these APIs can be resolved, but lots of functions are not found defined in multiple modules, such asVideoInfo::ComponentSize()
. This is because avisynth.h actually defines them with a proxying body to the linkage implementation. If linked dynamically, this will be the only definition, which is fine. However, when built statically, interface.cpp will be linked into my module, thus causing duplicate definition. The solution is to turn off the whole "linkage" mechanism for static linking including all the proxy definition. But that's big change.What I'm getting is either 3.7.0 is not ready for the static library, or the static library is for a completely different purpose that I'm not aware of. Otherwise, please provide some instructions. I'd like to statically link AviSynth+ instead of dealing with the dll loading situations. Thanks.