rochus-keller / Oberon

Oberon parser, code model & browser, compiler and IDE with debugger, and implementation of the Oberon+ language
GNU General Public License v2.0
448 stars 29 forks source link

License does not Allow Closed Source Development #41

Closed martinvahi closed 8 months ago

martinvahi commented 8 months ago

GCC and other compiler projects tend to have a GPL exception that states that the stdlib of the language is not under GPL. stdlib tends to be linked to the generated binaries/generated_code. Without the possibility to use the compiler for closed source development the compiler will become useless for freelancers like me, who have to deliver code that my clients can use as a closed source project. For example, software components under the the GNU Lesser General License are usable by me, because the GNU Lesser General License allows my clients' projects to stay closed source and I only have to publish my modifications to the components that others offered as open source software.

I am not a hypocrite with my such wishes, because the most restrictive license that I use for my own, personal, projects is BSD license.

Thank You for reading my comment.

rochus-keller commented 8 months ago

I'm mostly using GPL for "traditional" reasons without thinking much, and I actualy don't care what people are using the code for. The runtime stuff of my Oberon compiler is available under LGPL or MPL (see e.g. https://github.com/rochus-keller/Oberon/blob/master/runtime/Out.c). With that option you can do even comfortable static linking.

martinvahi commented 8 months ago

2023_12_20_Rochus_Keller_Oberon_compiler_GPL_linking_exception_type_1.pdf

I'll interpret Your current statement here then as the classical GPL linking exeption like it is with the GCC, where the GCC itself is under GPL, but the code that it generates or links during compilation is not under GPL. I'll use the PDF that I attached to my current comment as the linking exception document and consider that issue solved. Thank You for the answer and thank You for the software :-)

https://archive.ph/L5UF8

rochus-keller commented 8 months ago

Please note that I'm talking about the runtime, which is the code you find in the runtime subdirectory. It is this and only this code which is available under LGPL and MPL.

The compiler and IDE themselves are currently available under GPL which from my point of view doesn't restrict their use too much. Please check the license headers of the files you're interested in!

It is therefore wrong to interpret my statement as a general "linking exception" for the entire project.

but the code that it generates or links during compilation is not under GPL

This is a misconception. Something that is generated by an algorithm (i.e. not created by a human being) is by definition not subject to (international and local) copyright law. Therefore, the output of the compiler is not GPL, even if the compiler itself is GPL. The "linking exception" has nothing to do with this; it would only be relevant if you intended to use the compiler source code in your own project; in this case GPL applies.

I hope this has made things clear. The documents that you produce for yourself are not suitable as a substitute for the license conditions under which I release the code.

martinvahi commented 8 months ago

Thank You for the answer, but isn't it so that a compiler always LINKS the code or binary that it generates to the stdlib parts of the programming language that is used for writing the compilable code the compiler is compiling/translating to a binary or some generated code? stdlib code is part of the compiler project and the compiler reuses code blocks of the stdlib or compiled binaries of the stdlib to generate its output. That is the reason, why the GCC uses the "linking exception".

The GCC "linking exception" does not mean that GCC project code that is outside of the stdlib of the C/C++/whatever_GCC_supports could be linked to proprietary programs, because that would already be reusing the GCC in an arbitrary way as if it were some BSD-licensed or MIT-licensed software.

Something that is generated by an algorithm (i.e. not created by a human being) is by definition not subject to (international and local) copyright law. Therefore, the output of the compiler is not GPL, even if the compiler itself is GPL. The "linking exception" has nothing to do with this; it would only be relevant if you intended to use the compiler source code in your own project; in this case GPL applies.

If that were the case, then GCC would not need the "linking exception". I slightly repeat myself by writing here that the C/C++ stdlib IS PART OF THE COMPILER SOURCE CODE and IT GETS REUSED BY THE COMPILED BINARIES, which are separate projects from the compiler/GCC project. That is also the reason, why the ParaSail programming lanugage has the compiler under GPL, but ParaSail stdlib is allowed to be used in closed source programs. (Formally it was named "GCC Runtime Library Exception")

GCC_RUNTIME3_1.txt

Lawyers in court do not care, what somebody was thinking. They care about concrete licenses and any vagueness will be abused by whichever side that wants to abuse it. In my view Your last statement leaves things vague. I suggest that You write a clear statement to some LICENSE.txt that states clearly, whether closed source software can be compiled with the compiler without imposing any compiler related license to the compiler output AND THE STDLIB THAT THE COMPILER OUTPUT DEPENDS ON. Thank You.

rochus-keller commented 8 months ago

isn't it so that a compiler always LINKS the code or binary that it generates to the stdlib parts of the programming language that is used for writing the compilable code the compiler is compiling/translating to a binary or some generated code?

There are also compilers where this is not the case. But in the present case, my compiler generates either ECMA 335 assemblies or C99 files, and adds either the DLLs or C files from the runtime. Since the latter are available under LGPL or MPL, you are allowed to both dynamically or statically link of these runtime files to your application.

The GCC toolchain is different in this respect, since also the GCC runtime libraries (e.g. libc) are GPL; therefore FSF issued the GPL runtime library exception, which allows you to dynamically or statically link to libc. I find it more convenient to licence the runtime library under LGPL or MPL. If you build the C99 code generated by my compiler using GCC, the GCC runtime library exception issued by FSF also applies to you (see https://www.gnu.org/licenses/gcc-exception-3.1.html). In contrast the ECMA 335 assemblies directly run on the Mono runtime, which is available under an MIT license.

GCC project code that is outside of the stdlib of the C/C++/whatever_GCC_supports could be linked to proprietary programs, because that would already be reusing the GCC in an arbitrary way

That sounds like a misconception. If you generate C99 with my compiler, then the result is just another C project which you can compile with any C99 compatible compiler, and thus use the C runtime library und whatever license it is available. This doesn't violate e.g. the GCC runtime library exception in any way.

If that were the case, then GCC would not need the "linking exception"

No, because you still link machine generated code to the C runtime library, which itself is "human generated" and available under GPL with the runtim library exception.

In my view Your last statement leaves things vague.

No, and the legal situation is very clear. A judge would have no reason to come to a different conclusion.

write a clear statement to some LICENSE.txt that states clearly, whether closed source software can be compiled with the compiler without imposing any compiler related license to the compiler output AND THE STDLIB THAT THE COMPILER OUTPUT DEPENDS ON

Everything has already been laid out. The Oberon+ compiler is available under GPL, which doesn't restrict the use of the compiler in a commercial project. The Oberon+ runtime library on which the code generated by the Oberon+ compiler depends is available under LGPL or MPL, which again allows dynamic or static linking also with commercially used applications. In case you generated C99 code using the Oberon+ compiler, this code can be compiled with e.g. CLANG or GCC and linked with their runtime library subject to their license or runtime library exception.

Hope this helps.

martinvahi commented 8 months ago

Hope this helps.

It sure does. My current interpretation of Your answer is that Your compiler can be used for compiling closed source projects without imposing any license on those closed source projects by Your compiler project provided that those closed source projects depend only on other projects that allow closed source use and the runtime and stdlib of Your compiler. Thank You for Your answer and please correct me, if I'm wrong again. Until further corrections by You I'll use the attached PDF as a license clarification of Your compiler.

2023_12_23_Rochus_Keller_Oberon_compiler_license_clarification_type_1.pdf

rochus-keller commented 8 months ago

Your compiler can be used for compiling closed source projects without imposing any license on those closed source projects by Your compiler

correct

provided that those closed source projects depend only on other projects that allow closed source use and the runtime and stdlib of Your compiler

correct

And keep in mind that my project is work in progress and there might be bugs in the compiler, the generated code or the runtime library.

martinvahi commented 8 months ago

Thank You for the answer and feedback. Given Your sentence

And keep in mind that my project is work in progress and there might be bugs in the compiler, the generated code or the runtime library.

I have a temptation to mention that what I'm looking for by testing/studying various Oberon compilers is a set of properties. I'm not expecting the various Oberon compilers/translators to have those properties, may be the Oberon specification does not even theoretically allow those properties to exist, as of 2023_12_23 I'm just learning the Oberon programming language, but what I'm looking for is "a ambiguity-free C that does not depend on CPU bit-endianness, CPU byte-endianness and CPU register sizes". Like, if some unsigned 16bit number is defined in a language, then I could be sure that the operator "+" has a certain SPECIFICATION-WISE GUARANTEED behaviour at overflow situation, the byte-endianness is CONSTANT REGARDLESS OF CPU TYPE, bit-endianness is CONSTANT REGARDLESS OF CPU TYPE. The idea is that a program would be like a math formula in a sense that if one person writes it then another person can understand it decades or centuries later without having to ask the original author question like, "What does the '+' operator do if 8bit unsigned number has a value of 255 and it is added to another 8bit unsigned nunber that has a value of 1?" (Like, is the sum 0 or 256 or something else.) Or a situation, where

    some_8_bit_number := 255+2 ;
    another_8_bit_number := func_modify_some_bits(some_8_bit_number) ;

is expected to provide some concrete, well defined, mathematical result and the function works correctly only, if the bits have a specific bit-endianness.

What regards to Unicode/UTF-8or16orWhateverNofBits/some_other_Unicode_encoding then I see text as something that is related to source code and command-line IO. As of 2023_12 have NOT understood, why the C/C++ specification people have not defined a base type like UnicodeString2023 and in year 2030 the UnicodeString2030 would have the UnicodeString2023 string values as part of its subdomain, because Unicode standard is always backwards compatible and a compiler from year 2024 can instantly determine that code contains "unsupported type" UnicodeString2030. That way people could keep old code with fancy, BUT PRECISELY DEFINED, Unicode strings working and still use the newest or relatively new set of emoji-characters at their newest code. The spec may also say that the Unicode optional ByteOrderMark(BOM) is NOT optional in C/C++ source code and in binaries that contain the Unicode string constants. It would all just work, old code would keep on working, compiler implementation would not be "too cluttered" with weird "base types", etc. And no ambiguities.

As of 2023_12_24 the best way to create some C/C++ code that can handle future Unicode characters that have not been defined yet in 2023_12_24 is to convert Unicode strings to a series of Unicode codepoint numbers in ASCII, like

    "Hello 👽!"  --to-Unicode-codepoints--> "72, 101, 108, 108, 111, 32, 128125, 33"  
    search_result_as_a_commaseparated_list_of_unicode_codepoints := func_search_written_in_C_100_years_ago(
        "72, 101, 108, 108, 111, 32, 128125, 33")
    search_result_as_a_commaseparated_list_of_unicode_codepoints --from-Unicode-codepoints--> "🛸"

but as of 2023_12_24 I still do not know, how to write in pure C/C++ a code like

result_as_a_Unicode_string = func_search_written_in_C_or_Cpp("Hello 👽!");

Like, how would the string "Hello 👽!" be used as a string constant, if the C/C++ compiler may have Unicode/UTF8 support for source files, but not in the C/C++ programming language. Qt seems to translate its own C++ superset to some C++ that depends on Qt specific libraries, but I see the solution used in the Qt as a hack that is even more complex than the Unicode codepoints list based dirty hack that I described at my current comment. But if I could just find some programming language that has at least the bit-endianness and byte-endianness and variable sizes in bits and operators for all those types exactly defined, then I would be already happy with my finds even if the text side of the programming language is a mess.

Just giving some feedback, why I even try to look at Your Oberon compiler and other people's Oberon compilers. Thank You for Your answers and thank You for reading my comment(s).

rochus-keller commented 8 months ago

I'm afraid Oberon won't help you with that. The specification is not that detailed, and there is compiler-specific behavior. Oberon+ wants to be backwards compatible, and therefore does not have arbitrary design freedom.

Oberon+ (not original Oberon) specifies that source code files are UTF-8 according to ISO/IEC 10646. The CHAR type is specified to be Latin-1. The WCHAR type is specified to be of the Unicode BMP set (0x .. 0d7ffx, 0f900x .. 0ffffx).

martinvahi commented 8 months ago

Thank You for the answer.

I'm afraid Oberon won't help you with that. The specification is not that detailed, and there is compiler-specific behavior. Oberon+ wants to be backwards compatible, and therefore does not have arbitrary design freedom.

After reading the

https://people.inf.ethz.ch/wirth/Oberon/Oberon07.Report.pdf

I started to think that may be the Niklaus Wirth did not anticipate that his Pascal/Oberon/whatever_version_of_his_programming_language will be implemented like the TurboPascal was implemented, where the INTEGER is the integer type that the CPU hardware directly supports, with all of the integer overflows and the rest of the problems that come from having a predetermined constant number of bits for storing a value of a number. His own compilers tended to generate some Java bytecode analogue, p-code

https://homepages.cwi.nl/~steven/pascal/book/10pcode.html

or "m-code"

http://pascal.hansotten.com/uploads/pascalm/v14/Pascal-m%20M-code%20v1.4%20description.pdf

which was then interpreted very roughly like Java bytecode and then he obviously had many of the luxuries that "modern" (early 2000s) day interpreter developers have, including the possibility to decouple the integer storage space size from the sizes of the various CPU-registers.

Java, C, C++, C# all have that same flaw that the TurboPascal has: integer type is directly mapped to the fixed size integer that CPUs directly support, despite the fact that Java and C# have even the luxury of having at least some support for reflection. I love Ruby, because its authors, at least its core author, Yukihiro Matsumoto, did not run with the pack and took some time to think things trough and, in my very subjective view, got it right: integers are limited only by RAM size and one of the base types of Ruby is also what mathematicians call "rational numbers", essentially fractions that can be written with two integers. Even the class name in Ruby for that number type is Rational. No issues with any rounding errors that ruin the calculation of inverse matrices. What regards to the issue that the memory consumption of those rational numbers can get pretty big relatively quickly, then that can be countered by manually specifying at one's own written calculations code, where and how much must be rounded so that the rounding errors won't ruin the calculation.

That is to say, may be that is the explanation, why such a thing like "integer overflow" or "integer storage space size" is not even mentioned at the Niklaus Wirth Oberon specification, "Oberon Report".

Fun fact: the Oberon language spec PDF does not contain even a single instance of the word "memory".

Thank You for Your answer and thank You for reading my comment :-)

rochus-keller commented 8 months ago

There is something called HUGEINT in Active Oberon which might be closer to what you're looking for. I think "integers are limited only by RAM size" is something which can be implemented in a library and should not be a direct language feature for a language which tries to be "as simple as possible".

Concerning the Oberon language spec, a guiding principle seems to have been to not be longer than 16 pages. It neither mentions errors or error handling (see https://oberon-lang.github.io/2022/05/15/towards-exception-handling.html).