<div dir="ltr"><div><div><div><div>Yes, in my case, `main` is in the runtime library and is the first thing that runs from MY code, and in turn calls the __PascalMain that the compiler generated. The compiler knows about certain built-in functions such as `write` and `writeln`, and will replace those with corresponding calls to the runtime library function equivalent. <br><br></div>Of course, you can either completely forego the convenience of the C library, and implement your own library, starting with Linux or Windows system calls written in assembler [and if you plan on supporting further OS's, obviously you need to implement those too] - it's worth noting that system calls are different per architecture, so if you plan on supporting more than x86-32 and x86-64, you will need to write assembler code for each of those too. Oh, and system calls are quite different between OS's.<br><br>You will then be able to simply call `ld -o name-supplied-by-compiler object-files-supplied-by-compiler -lyour-runtime.a`. I decided to go the simple route of using the already existing C runtime for file and console I/O, random number, a few floating point functions and some other functions. Because I'm a bit lazy and think that it's OK to do that. Like I said early in this thread, I do have some plans to replace this in the future, but it's nowhere near the top of the todo-list. <br><br></div>Just as a reference, the `ld` line of my compiler is:<br><div><div><br>/usr/bin/ld"
--hash-style=gnu --no-add-needed --build-id --eh-frame-hdr -m
elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o gol
/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../lib64/crt1.o
/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-redhat-linux/4.9.2/crtbegin.o
-L/home/mats/src/lacsap -L/usr/lib/gcc/x86_64-redhat-linux/4.9.2
-L/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../lib64
-L/usr/local/bin/../lib64 -L/lib/../lib64 -L/usr/lib/../lib64
-L/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../..
-L/usr/local/bin/../lib -L/lib -L/usr/lib gol.o -lruntime -lm -lgcc
--as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s
--no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.9.2/crtend.o
/usr/lib/gcc/x86_64-redhat-linux/4.9.2/../../../../lib64/crtn.o<br><br></div>Looking at that, you can probably understand why I decided to NOT write a bit of code that finds and links to all of those things myself.<br><br>--<br></div><div>Mats<br></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 20 March 2016 at 15:35, Lorenzo Laneve <span dir="ltr"><<a href="mailto:lore97drk@icloud.com" target="_blank">lore97drk@icloud.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div>I think I'll have to do as you did for the runtime, but will the lib's main function be the resulting program's real main function? And your __PascalMain implementation is in the object file your compiler created, isn't it?</div><div>We can say that the main function a programmer writes is not the very first thing that is called in the final program (well obviously). </div><div><br></div><div>Replying to the suggestion you told me about calling the C compiler to finish the job, I know I can do it, but I don't want because I want my compiler to be standalone.</div><div><div class="h5"><div><br>On Mar 20, 2016, at 2:02 PM, mats petersson <<a href="mailto:mats@planetcatfish.com" target="_blank">mats@planetcatfish.com</a>> wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr"><div><div><div><div><div>Adding back the "all recipients" - sorry, sending message from my phone, I forgot... <br><br></div>Since my runtime is for a Pascal compiler, it has to "adapt" the C startup into a suitable Pascal environment. This means running the init portion of other modules as well as discarding the argc, argv arguments. So, I have a C main, which calls __PascalMain, which is the "main" for the pascal program itself after some other setup code.<br><br></div>The whole runtime of C is quite complex (in terms of "what code is executed in what order", at least), and C++ is a little worse on top of that, but basically there is code "before main" in C. If you don't use the C library, you will probably have to replace this by some other code that does something similar.<br><br></div>But assuming you don't have a very good reason for doing so, I would certainly suggest that you make your code simply pass the .bc or .o file that your compiler generates to the C compiler.<br><br></div>I would also ignore things like "is it faster to do puts than fputc" - at least until you have other things working reasonably well. This according to the principle of "avoid premature optimisat". Unless you are really familiar with how compilers work and the design thereof, you have "bigger fish to fry" than micro-optimising your string output... I have two years of experience in writing my own LLVM frontend, and I guarantee that optimising string output is dead easy to do "later". Getting the compiler to deal with some of the more complex parts of whatever language it is will not be... <br><br>--<br></div>Mats<br><div><div><div><div><div><div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On 20 March 2016 at 12:34, Lorenzo Laneve <span dir="ltr"><<a href="mailto:lore97drk@icloud.com" target="_blank">lore97drk@icloud.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div>My goal is a complete and independent compiler for a new, safe and portable programming language.</div><div>I read the code you put the link of earlier, but I still don't get it. If I link against that library will that main function included and started on the resulting program?</div><div>And yeah for example I have to initialize stdout, I have to call it before my main function. The runtime library does the trick but I didn't get the main function in your library</div><div><div><div><br>On Mar 20, 2016, at 1:11 PM, mats petersson <<a href="mailto:mats@planetcatfish.com" target="_blank">mats@planetcatfish.com</a>> wrote:<br><br></div><blockquote type="cite"><div><p dir="ltr"><br>
On 20 Mar 2016 11:13, "Lorenzo Laneve" <<a href="mailto:lore97drk@icloud.com" target="_blank">lore97drk@icloud.com</a>> wrote:<br>
><br>
> So won't my program have as main function the main function declared in the IR? </p>
<p dir="ltr">Depends on the linker script (which is "prepared by the compiler vendor" if you use clang or gcc).</p>
<p dir="ltr">There will be a statement of "start here" somewhere. It usually isn't "main" but something that runs "global constructors" and various other "needed before main" work.</p>
<p dir="ltr">Of course, if you don't use "stdout" and "stdin", and don't need "malloc", etc, etc, you can start directly at main. You have to write your own linker script to do that tho'.</p>
<p dir="ltr">What us your final goal?</p>
<p dir="ltr">--<br>
Mats<br>
><br>
> On Mar 20, 2016, at 9:03 AM, mats petersson <<a href="mailto:mats@planetcatfish.com" target="_blank">mats@planetcatfish.com</a>> wrote:<br>
><br>
>><br>
>><br>
>> On 19 March 2016 at 22:15, Lorenzo Laneve <<a href="mailto:lore97drk@icloud.com" target="_blank">lore97drk@icloud.com</a>> wrote:<br>
>>><br>
>>> @james<br>
>>> Yeah for code generation I figured out that clang doesn't actually use llc, and I already started reading its code to see how it works.<br>
>>> For the ld, there's not an "helper" in the llvm library that calls it, is there?<br>
>>> By the way, I thought about calling ld with things like execl() or std::system(), I don't know if it's a good idea, I'm always afraid there are better ways than mine!<br>
>>><br>
>>><br>
>>> @mats<br>
>>> Yea, I haven't used C's system calls in my own code yet but if I just have to declare the function puts in the IR modules (e.g.: putc) and then link against libc, am I right?<br>
>>> Should I use basic C functions such as putc() and getc(), in my runtime library or is there a more efficient way to set up my runtime library?<br>
>><br>
>><br>
>> That is what I mean by using C runtime calls: You are calling into C functions in libc, so you need:<br>
>> 1. Link to libc.<br>
>> 2. run libc startup code.<br>
>> 3. call your program's `main` from the libc startup code.<br>
>><br>
>> To get this working, you need to either extract/construct the long list of arguments to `ld` (or whatever linker is used in the system) - I looked at doing that, but it gets really messy if you want to support running on anything other than your very own machine, since libraries are installed in different places on different systems [sure, they are "findable", but it's a fairly messy process still]. And of course, you may need `libm` as well, and other parts that in turn depend on the C library - very few libraries written in C are completely independent, most will at the very least call printf or fprintf in their "Help, something didn't work" functions.... <br>
>><br>
>> Of course, since I'm implementing a "real" language with previously defined functionality for I/O, I'm more reliant on specific behaviour than if I were implementing a language with "my own definition". Having said that, even doing a "simple" putc is quite a few lines of code, including some inline assembler, I think.<br>
>><br>
>> The alternative is to have your completely separate functions for I/O and whatever else you need from the system. But if you are interested in writing your own compiler, rather than interested in writing your own OS interface libraries, I'd suggest that you just (more or less directly) interface to the C library. It's relatively easy [as long as your compiler has sane calling conventions, etc] and solves the immediate problem without too much effort.<br>
>><br>
>> What I did:<br>
>> <a href="https://github.com/Leporacanthicus/lacsap/tree/master/runtime" target="_blank">https://github.com/Leporacanthicus/lacsap/tree/master/runtime</a><br>
>><br>
>> Originally, my runtime was one monolithic .c file, with a couple dozen functions, but as it grew, I decided to move it into separate parts. <br>
>><br>
>> Obviously, there are OTHER solutions, but I don't know of a way that trivially removes the need for a libc linkage.<br>
>><br>
>> --<br>
>> Mats<br>
>>><br>
>>><br>
>>> On Mar 19, 2016, at 9:58 PM, mats petersson <<a href="mailto:mats@planetcatfish.com" target="_blank">mats@planetcatfish.com</a>> wrote:<br>
>>><br>
>>>> If you plan on calling C runtime library functions, you probably want to do what I did:<br>
>>>> Cheat, and make a libruntime.a (with C functions to do stuff your compiler can't do natively) and then link that using clang or gcc. <br>
>>>><br>
>>>> <a href="https://github.com/Leporacanthicus/lacsap/blob/master/binary.cpp#L124" target="_blank">https://github.com/Leporacanthicus/lacsap/blob/master/binary.cpp#L124</a><br>
>>>><br>
>>>> At some point, I plan to replace my runtime library with native Pascal code, at which point I will be able to generate the ELF binary straight from my compiler without the runtime library linking in the C runtime library, but that's not happening anytime real soon. Getting the compiler to compile v5 of Wirth's original Pascal compiler is higher on the list... :)<br>
>>>><br>
>>>> --<br>
>>>> Mats<br>
>>>><br>
>>>> On 19 March 2016 at 20:51, James Molloy via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br>
>>>>><br>
>>>>> Hi Lorenzo,<br>
>>>>><br>
>>>>> Clang doesn't call llc; LLVM is compiled into Clang. Clang does call the system linker though.<br>
>>>>><br>
>>>>> Making your compiler generate *object* code is very simple. Making it fixup that object code and execute it in memory (JIT style) is also simple. Linking it properly and creating a fixed up ELF file is less simple. For that, you need to compile to object (using addPassesToEmitFile() - see llc.cpp) then invoke a linker. Getting that command line right can be quite difficult.<br>
>>>>><br>
>>>>> Rafael, This would be a good usecase for LLD as a library. I heard that this is is an explicit non-goal, which really surprised me. Is that indeed the case?<br>
>>>>><br>
>>>>> Cheers,<br>
>>>>><br>
>>>>> James<br>
>>>>><br>
>>>>> On Sat, 19 Mar 2016 at 13:32 Lorenzo Laneve via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br>
>>>>>><br>
>>>>>> I'd like to make my compiler independent, just like Clang. Doesn't Clang call llc and then system's ld by itself? I don't want my compiler to depend by any other program.<br>
>>>>>> I guess there will be a class in the llvm library that generates the object files based on the system's triple and data layout, and then call the system's ld?<br>
>>>>>><br>
>>>>>> On Mar 19, 2016, at 11:48 AM, Bruce Hoult <<a href="mailto:bruce@hoult.org" target="_blank">bruce@hoult.org</a>> wrote:<br>
>>>>>><br>
>>>>>>> If you've created a .bc or a .ll file then the simplest thing is to just give it to clang exactly the same as you would for a .c file. Clang will just Do The Right Thing with it.<br>
>>>>>>><br>
>>>>>>> If you don't want to link, then pass flags such as -c to clang as usual.<br>
>>>>>>><br>
>>>>>>> e.g.<br>
>>>>>>><br>
>>>>>>> ---- hello.ll ----<br>
>>>>>>> declare i32 @puts(i8*)<br>
>>>>>>> @str = constant [12 x i8] c"Hello World\00"<br>
>>>>>>><br>
>>>>>>> define i32 @main() {<br>
>>>>>>> %1 = call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @str, i64 0, i64 0))<br>
>>>>>>> ret i32 0<br>
>>>>>>> }<br>
>>>>>>> ----------------<br>
>>>>>>><br>
>>>>>>> $ clang hello.ll -o hello && ./hello<br>
>>>>>>> warning: overriding the module target triple with x86_64-apple-macosx10.10.0<br>
>>>>>>> 1 warning generated.<br>
>>>>>>> Hello World<br>
>>>>>>><br>
>>>>>>><br>
>>>>>>> On Sat, Mar 19, 2016 at 3:03 AM, Lorenzo Laneve via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br>
>>>>>>>><br>
>>>>>>>> I wrote my compiler and now it generates LLVM IR modules. Now i’d like to go ahead and make object file and then executable, just like clang does.<br>
>>>>>>>><br>
>>>>>>>> What should I have to use to create the object files? and then how do I call the ld? (not llvm-ld, I want my compiler to work like Clang and I read that Clang doesn’t use llvm-ld).<br>
>>>>>>>> _______________________________________________<br>
>>>>>>>> LLVM Developers mailing list<br>
>>>>>>>> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
>>>>>>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
>>>>>>><br>
>>>>>>><br>
>>>>>> _______________________________________________<br>
>>>>>> LLVM Developers mailing list<br>
>>>>>> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
>>>>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
>>>>><br>
>>>>><br>
>>>>> _______________________________________________<br>
>>>>> LLVM Developers mailing list<br>
>>>>> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
>>>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
>>>>><br>
>>>><br>
>><br>
</p>
</div></blockquote></div></div></div></blockquote></div><br></div></div></div></div></div></div></div></div></div></div>
</div></blockquote></div></div></div></blockquote></div><br></div>