Can I implicitly link against OCC in a closed source Visual Studio application?

Hello,

The prebuilt Windows installer comes with a set of static libraries (e.g., TKBin.lib) in addition to the dlls. I think these might be all import libraries which are used for the purposes of implicit linking with the DLLs because Visual Studio's LINK.exe is not capable of linking with PE binaries (.dlls, .exes), only COFF binaries (.obj, .lib) [1].

I'd like to use them for a closed source project but I'm not sure if that would only be legal if all the object files of the closed source program were released as well.

Does the LGPL consider implicit linking as static or dynamic linking?

It's not clear to me whether implicit linking is "dynamic linking" because it involves a static import library. Most articles on the LGPL seem to be written with GCC in mind. GCC can conveniently link directly against .so files without a static import library, Visual Studio can't.

I tried to find some information on the internet about how this applied to other projects:

I Found one post saying “it’s not a big deal”
- https://www.gamedev.net/forums/topic/696853-lgpl-dll-headers-and-import-...

I found two posts saying "it might be a concern":
- FLTK: https://fltk-dev.easysw.narkive.com/oZmG1AzK/dynamic-linking-with-vs-2010
- R project: https://svn.r-project.org/R/trunk/doc/COPYRIGHTS

I think the LGPL might force somebody to release all the object files of a closed source application, if:

(I couldn't find a solid answer to these)

- Statically linking against an import library would tie the closed source application to one specific version of OCC,

- static import libraries themselves are considered an "LGPL" library and part of OCC,

- or, the .lib files provided with OCC are not actually import libraries and contain more than "stubs"

All this is important because, unfortunately, I wouldn't be able to release all the object files of the project

One other critical static library would be from a third party and I cannot release it publicly under any circumstance

From a purely technical perspective, the ideal setup would be if OCC's static import libraries and that proprietary static library could coexist together in the same dll or executable

- The reason why that would be ideal is there's a significant amount of boilerplate / conversion code that would need to be written to make the proprietary library understand OCC models, and it would be easiest to write that if I could access the OCC model using the OCC API

- I could, e.g., load a brep model using OCC, access it using the OCC apis and convert it to the format the proprietary library needs in the same dll.

If I can't use both the OCC and proprietary APIs in the same dll, I would have to either add wrapper DLLs, or convert all the OCC model data into some generic API

- E.g., I could load a brep model using OCC, store all the vertexes/edges/faces/etc. in some generic container like std::vector<GenericPoint>, and then pass that to the dll containing the proprietary library and use no OCC APIs in that proprietary library.

- It would be a good bit of extra code, and more memory usage, I'd rather avoid it but I think it might be doable.

Let me know if you have any suggestions, thanks,

- J

Kirill Gavrilov's picture

I think that "Open CASCADE Exception" to LGPL was intended to cover this tricky part as well:

The object code (i.e. not a source) form of a "work that uses the Library" can incorporate material from a header file that is part of the Library.

John W's picture

Thanks, it is good to know I could use the header files.

Though, I don't see anything in the license about the provided static library files.

It still says

When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library.

and

However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.

Kirill Gavrilov's picture

I've thought what you are talking about is that .DLL + .LIB files are not exactly the same thing as linking to .SO files on Linux. In that case, I guess what may come into .LIB files is what is defined by headers and what cannot be easily overridden by another library. This is just how dynamic linking is implemented in Windows and not something to bother about (and using GCC/MinGW instead of Visul Studio would unlikely change a thing).

But if you are talking about "true" static libraries, then I believe that LGPL was intentionally meant to prevent such uses and force copy-left part of the license here, although it's wording is not exact and it could be technically possible (but clumsy and disputable) to use statically linked LGPL library by sharing object files necessary with instructions allowing to rebuild application with modified library. This is not the same thing as sharing the source code of application.

I don't think that such complications with static linking are justified on normal systems like Windows, Linux or macOS, where DLL/SO/DYLIB files could be (relatively) easily replaced. But platforms with incomplete or restricted support of dynamic libraries (like iOS or WebAssembly) go deeply into gray zone of uncertainty - is it possible or not legally using LGPL library there within a proprietary application?

John W's picture

Hi Kirill,

Yes, .DLL/.LIB is not quite the same thing as it is in GCC. In GCC you can link directly to a .so file, but in Visual Studio, the only way to do that is by using LoadLibrary, which is the Windows equivalent of Linux's dlopen.

One thing I have to nitpick on, it's not Windows that causes this problem, it's Visual Studio. MinGW on Windows actually can dynamically link directly against .dlls, but Visual Studio can't. That doesn't help us much though, because the proprietary lib is Visual Studio.

In Linux or MinGW dynamic linking is as simple as just -lSomeLibrary, with some file named SomeLibrary.so or SomeLibrary.dll. Visual Studio has the -l option too, it's called "implicit linking", but unlike GCC Visual Studio needs an intermediate .lib file to make that work (see this page for more information). The only other way to link is explicit linking (i.e., LoadLibrary/dlopen).

But if you are talking about "true" static libraries, then I believe that LGPL was intentionally meant to prevent such uses and force copy-left part of the license here,

It's a bit unclear what a "true" static library is, these static "import libraries" from what I read contain little more than just the addresses of functions and stubs that Visual Studio generates automatically in response to __declspec(dllexport). Unfortunately Visual Studio is a closed source black box so I can't really verify this (the disassembly does not give many clues).

I think you are right though, and these libraries would trigger copyleft (even if they are not much more than function pointer address containers or stubs), which we unfortunately could not support. I think there would be no issues at all releasing the object files we own, but the proprietary static library... not so much.

to use statically linked LGPL library by sharing object files necessary with instructions allowing to rebuild application with modified library.

Unfortunately, we couldn't provide these instructions because we would have to provide a download link to the prorietary static library we don't own and can't distribute.

is it possible or not legally using LGPL library there within a proprietary application?

I'm not sure either (I haven't been in this situation before, I either made 100% proprietary software or 100% FOSS software). The way it looks to me, I think the only way to use a LGPL component in a proprietary program is to

A) put it in its own DLL, 

B) have permission to release every object in there, even if it's not your IP,

or C) explicit LoadLibrary every dll by name at runtime (and deal with name mangling/decoration, etc.)

Or...

This is just how dynamic linking is implemented in Windows

I've heard this reasoning too, I would say that's the "practical" answer. Visual Studio is not as powerful as GCC in this respect and it needs more files for linking. I don't know if import libraries would be considered the same as header files though.

Kirill Gavrilov's picture

MinGW on Windows actually can dynamically link directly against .dlls, but Visual Studio can't. That doesn't help us much though, because the proprietary lib is Visual Studio.

I've never heard about this option in MinGW. Where did you found it?

I've heard this reasoning too, I would say that's the "practical" answer. Visual Studio is not as powerful as GCC

I'm not quite understand what is the actual problem with .LIB + .DLL (apart from some low-level implementation details). From my understanding, LGPL wording was meant to allow superseding a (dynamic) library with modified one. Is there some problem with replacing .DLL in case of .EXE + .DLL distribution? Or there is some meaning to be able to replace something important encoded in .LIB (what exactly?) making .DLL substitution useless or impossible?

John W's picture

Hi Kirill,

I never hear about this option in MinGW. Where did you found it?

See this post: https://stackoverflow.com/questions/27824102/how-do-import-libraries-wor...

Is there some problem with replacing .DLL in case of .EXE + .DLL distribution? Or there is some meaning to be able to replace something important encoded in .LIB (what exactly?) making .DLL substitution useless or impossible?

I don't know, but that's what I'd like to find out.

- The technical side, I think I can test.

- The legal side "are static libraries part of OCC?" question, though, I can't find an answer to.

Kirill Gavrilov's picture

- The legal side "are static libraries part of OCC?" question, though, I can't find an answer to.

That's the common issue with software licenses - you will NOT find any reliable answers on user forums. You will find only guesses and personal interpretations of a license text with INAL (I'm not a lawyer) comment - as only a lawyer may give you a legal advice (cannot say, though, if this advice would be correct). Note, that this should be your personal lawyer - it is not helpful asking such questions to a distributor of software, as their lawyers would usually arise only in case of a real legal conflict.

And if you have any fears on technical appliance to LGPL in your project, there is always an option to sign a commercial contract with Open Cascade and use OCCT under commercial license (as you may see from OCCT header files - it is dual-licensed).