Thread overview
Have you ever tried to compile for esp32/8266?
Nov 19, 2019
Andrea Fontana
Nov 19, 2019
kinke
Nov 26, 2019
dangbinghoo
Nov 26, 2019
dangbinghoo
Nov 26, 2019
Paul Freund
Nov 26, 2019
dangbinghoo
Nov 27, 2019
Paul Freund
Nov 28, 2019
dangbinghoo
November 19, 2019
I see expressif released a fork of llvm with a new target: extensa.
This allows you to write code for esp8266 and esp32 using clang [1]

I wonder if we can use ldc (using -betterC I guess) to build code for these platforms as well.

Any idea?

[1] https://esp32.com/viewtopic.php?t=9226&p=38466
November 19, 2019
On Tuesday, 19 November 2019 at 12:51:06 UTC, Andrea Fontana wrote:
> I see expressif released a fork of llvm with a new target: extensa.
> This allows you to write code for esp8266 and esp32 using clang [1]
>
> I wonder if we can use ldc (using -betterC I guess) to build code for these platforms as well.
>
> Any idea?
>
> [1] https://esp32.com/viewtopic.php?t=9226&p=38466

A guy has already been experimenting with it: https://forum.dlang.org/post/slopmwagueijibteaihu@forum.dlang.org
November 19, 2019
On Tuesday, 19 November 2019 at 12:51:06 UTC, Andrea Fontana wrote:
> I see expressif released a fork of llvm with a new target: extensa.
> This allows you to write code for esp8266 and esp32 using clang [1]
>
> I wonder if we can use ldc (using -betterC I guess) to build code for these platforms as well.
>
> Any idea?
>
> [1] https://esp32.com/viewtopic.php?t=9226&p=38466

I think it's enough to generate llvm ir with the "-output-ll -betterC" flags, then the generated file can easily be compiled from llc of llvm extensa
November 26, 2019
On Tuesday, 19 November 2019 at 12:51:06 UTC, Andrea Fontana wrote:
> I see expressif released a fork of llvm with a new target: extensa.
> This allows you to write code for esp8266 and esp32 using clang [1]
>
> I wonder if we can use ldc (using -betterC I guess) to build code for these platforms as well.
>
> Any idea?
>
> [1] https://esp32.com/viewtopic.php?t=9226&p=38466

the toolchain building commands:

1. get the llvm and clang source for xtensa

  git clone https://github.com/espressif/llvm-xtensa.git
  git clone https://github.com/espressif/clang-xtensa.git llvm-xtensa/tools/clang

2. build llvm-clang for xtensa

    mkdir llvm_build
    cd llvm_build

    # from https://gist.github.com/MabezDev/26e175790f84f2f2b0f9bca4e63275d1
    cmake ../llvm-xtensa -DLLVM_TARGETS_TO_BUILD="Xtensa" -DCMAKE_BUILD_TYPE=Release -G "Ninja" -D CMAKE_INSTALL_PREFIX=/opt/llvm-xtensa

    # Take a while
    cmake --build . OR ninja
    ninja install

3. build ldc2 from source using above llvm

    get ldc source, I just used ldc-1.19.0-beta1-src.tar.gz

    mkdir build-ldc

    cmake -G Ninja ../ldc_source_dir -DCMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/opt/ldc-xtensa -DLLVM_ROOT_DIR=/opt/llvm-xtensa
    ninja ldc2

And you may experience this:

```
 Linking CXX executable bin/ldc2
FAILED: bin/ldc2
: && /usr/bin/c++  -DDMDV2 -DHAVE_SC_ARG_MAX -O3 -DNDEBUG  -rdynamic obj/ldc2.o  -o bin/ldc2  lib/libldc.a -lLLVMWindowsManifest -lLLVMMCDisassembler -lLLVMLTO -lLLVMPasses -lLLVMObjCARCOpts -lLLVMLibDriver -lLLVMOption -lLLVMipo -lLLVMInstrumentation -lLLVMVectorize -lLLVMLinker -lLLVMIRReader -lLLVMDebugInfoPDB -lLLVMDebugInfoDWARF -lLLVMAsmParser -lLLVMXtensaCodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMDebugInfoCodeView -lLLVMDebugInfoMSF -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMBitWriter -lLLVMXtensaAsmParser -lLLVMXtensaDesc -lLLVMXtensaInfo -lLLVMTarget -lLLVMAnalysis -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMBitReader -lLLVMCore -lLLVMBinaryFormat -lLLVMXtensaAsmPrinter -lLLVMMC -lLLVMSupport -lLLVMDemangle -L/opt/llvm-xtensa/lib -lz -lrt -ldl -ltinfo -lpthread -lm -lxml2 -Wl,--export-dynamic -fuse-ld=gold -L/usr/lib -lphobos2-ldc-shared -ldruntime-ldc-shared -Wl,-rpath,/usr/lib -Wl,--gc-sections -lrt -ldl -lpthread -lm -m64 -ldl -ltinfo -lpthread -lm -lxml2 && :
lib/libldc.a(main.cpp.o):main.cpp:function cppmain(): error: undefined reference to 'llvm::initializeGlobalISel(llvm::PassRegistry&)'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
```

Edit build.ninja , search `build bin/ldc2:` and edit LINK_LIBRARIES  add `-lLLVMGlobalISel` before `-lLLVMCodeGen`
and `ninja ldc2` again.

Then we got ldc2 for xtensa in build-ldc/bin

4. test

vim test.d

void d_func ()
{
        int[4] arr;
        auto c = arr.length;
}

```
build-ldc2/bin/ldc2 -mtriple=xtensa-esp32-elf -mcpu=esp32 -gcc=xtensa-esp32-elf-gcc -betterC -dip1000 -boundscheck=off -linkonce-templates test.d -c

$ file test.o
test.o: ELF 32-bit LSB relocatable, Tensilica Xtensa, version 1 (SYSV), not stripped

$ readelf -s  test.o

Symbol table '.symtab' contains 4 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS test.d
     2: 00000000     0 SECTION LOCAL  DEFAULT    4
     3: 00000000    24 FUNC    GLOBAL DEFAULT    4 _D4test6d_funcFZv
```

You can put the long compiler command into a shell script:

```
$ cat xtensa-ldc
#!/bin/sh

export PATH=${HOME}/esp/xtensa-esp32-elf-5/bin:${PATH}
build-ldc/bin/ldc2 -mtriple=xtensa-esp32-elf -mcpu=esp32 -gcc=xtensa-esp32-elf-gcc -betterC -dip1000 -boundscheck=off -linkonce-templates $@

5. integrate with IDF as a component

create a component called `dcode`, and write this style of makefile:

```
$ cat component.mk

    $(COMPONENT_LIBRARY):dcode.a

    SRC := $(wildcard $(COMPONENT_PATH)/*.d)
    COMOBJS := $(patsubst %.d, %.o, $(SRC))

    %.o : %.d
        ldc2-xtensa -c $< -of=$@

    COMPONENT_ADD_LDFLAGS += $(COMPONENT_BUILD_DIR)/dcodelib.a

    dcodelib :
        xtensa-esp32-elf-ar rc $(COMPONENT_BUILD_DIR)/dcodelib.a $(COMOBJS)

    dcode.a: $(SRC) $(COMOBJS) dcodelib
```

And you will have betterC d code compiles and linking:

```
$ cat dcode.d

module dcode;

extern(C) int printf (scope const char * fmt, ...);

char[8] a = ['a'];

extern (C) void dlang_main()
{
    uint i = 0;


    printf("hello, dlang says : i = %d, char a len = %d\r\n", i, a.length);
}







November 26, 2019
On Tuesday, 26 November 2019 at 04:34:44 UTC, dangbinghoo wrote:
> On Tuesday, 19 November 2019 at 12:51:06 UTC, Andrea Fontana wrote:
>> I see expressif released a fork of llvm with a new target: extensa.
>> This allows you to write code for esp8266 and esp32 using clang [1]
>>
>> I wonder if we can use ldc (using -betterC I guess) to build code for these platforms as well.
>>
>
> And you will have betterC d code compiles and linking:
>
> ```
> $ cat dcode.d
>
> module dcode;
>
> extern(C) int printf (scope const char * fmt, ...);
>
> char[8] a = ['a'];
>
> extern (C) void dlang_main()
> {
>     uint i = 0;
>
>
>     printf("hello, dlang says : i = %d, char a len = %d\r\n", i, a.length);
> }

PS: and in other place of you esp32 IDF C code, just call dlang_main as a pain c function, you will probably see Dlang is saying hello.

^_^

Hope these helps!

Thanks!

----
Binghoo Dang


November 26, 2019
On Tuesday, 26 November 2019 at 04:38:17 UTC, dangbinghoo wrote:
> On Tuesday, 26 November 2019 at 04:34:44 UTC, dangbinghoo wrote:
>> On Tuesday, 19 November 2019 at 12:51:06 UTC, Andrea Fontana wrote:
>>> I see expressif released a fork of llvm with a new target: extensa.
>>> This allows you to write code for esp8266 and esp32 using clang [1]
>>>
>>> I wonder if we can use ldc (using -betterC I guess) to build code for these platforms as well.
>>>
>>
>> And you will have betterC d code compiles and linking:
>>
>> ```
>> $ cat dcode.d
>>
>> module dcode;
>>
>> extern(C) int printf (scope const char * fmt, ...);
>>
>> char[8] a = ['a'];
>>
>> extern (C) void dlang_main()
>> {
>>     uint i = 0;
>>
>>
>>     printf("hello, dlang says : i = %d, char a len = %d\r\n", i, a.length);
>> }
>
> PS: and in other place of you esp32 IDF C code, just call dlang_main as a pain c function, you will probably see Dlang is saying hello.
>
> ^_^
>
> Hope these helps!
>
> Thanks!
>
> ----
> Binghoo Dang

Thank you very much for your fantastic work! I did your instructions on WSL Debian but had to change the build configuration for llvm-xtensa according to the link you posted

cmake ../llvm-xtensa -DLLVM_TARGETS_TO_BUILD="Xtensa;X86" -DCMAKE_BUILD_TYPE=Release -G "Ninja" -DCMAKE_INSTALL_PREFIX=/opt/llvm-xtensa

without the X86 build target llvm-config complains about a missing X86disassembler component. I am currently working on a template project for ESP-IDF with D support that makes compilation very easy and includes instructions/scripts to get it working, you saved me from a lot of work :)

November 26, 2019
On Tuesday, 26 November 2019 at 12:17:51 UTC, Paul Freund wrote:
> without the X86 build target llvm-config complains about a missing X86disassembler component. I am currently working on a template project for ESP-IDF with D support that makes compilation very easy and includes instructions/scripts to get it working, you saved me from a lot of work :)

you're welcome.

the makefile I posted should work making the D code building as a common C component.

---
Binghoo dang

November 27, 2019
On Tuesday, 26 November 2019 at 13:28:13 UTC, dangbinghoo wrote:
> On Tuesday, 26 November 2019 at 12:17:51 UTC, Paul Freund wrote:
>> without the X86 build target llvm-config complains about a missing X86disassembler component. I am currently working on a template project for ESP-IDF with D support that makes compilation very easy and includes instructions/scripts to get it working, you saved me from a lot of work :)
>
> you're welcome.
>
> the makefile I posted should work making the D code building as a common C component.
>
> ---
> Binghoo dang

It is still very unpolished but here https://github.com/PaulFreund/ESP32_Dlang_Template is a project template that should include all required steps to take to get your minimal D example running on a real ESP32 (tested, works!) based on either Debian or Windows Subsystem for Linux - Debian. I definitely want to include support for CMake compilation and a few other goodies.


November 28, 2019
On Wednesday, 27 November 2019 at 09:10:10 UTC, Paul Freund wrote:
> On Tuesday, 26 November 2019 at 13:28:13 UTC, dangbinghoo wrote:
>> On Tuesday, 26 November 2019 at 12:17:51 UTC, Paul Freund

> It is still very unpolished but here https://github.com/PaulFreund/ESP32_Dlang_Template is a project template that should include all required steps to take to get your minimal D example running on a real ESP32 (tested, works!) based on either Debian or Windows Subsystem for Linux - Debian. I definitely want to include support for CMake compilation and a few other goodies.

That's great!

maybe the dcode component makefile needs some tweak, the makefile I posted has a little problem: the D code compiled object was placed in the some dir with D sources, should be fixed.


---
binghoo dang