Have you ever tried to compile for esp32/8266?

dangbinghoo dangbinghoo at gmail.com
Tue Nov 26 04:34:44 UTC 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);
}









More information about the digitalmars-d-ldc mailing list