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