https://wiki.dlang.org/api.php?action=feedcontributions&user=Dangbinghoo&feedformat=atom
D Wiki - User contributions [en]
2024-03-28T13:02:26Z
User contributions
MediaWiki 1.31.2
https://wiki.dlang.org/?title=D_on_esp32/esp8266(llvm-xtensa%2Bldc)_and_how_to_get_started&diff=9716
D on esp32/esp8266(llvm-xtensa+ldc) and how to get started
2019-11-26T08:23:47Z
<p>Dangbinghoo: Created page with "The Rust community has proved that Rust is running on ESP32. I just looked at that tutorial and then had an idea: is D's betterC running on ESP32? hmm, it should be! For those..."</p>
<hr />
<div>The Rust community has proved that Rust is running on ESP32. I just looked at that tutorial and then had an idea: is D's betterC running on ESP32? hmm, it should be!<br />
For those who don't know what ESP32 is:<br />
<small>ESP32 is a low-cost low power consumption WiFi/BLE soc chip with up to 240Mhz 32bit Xtensa CPU and 520KB RAM and SPI nor flash support, and it's a star in the IoT device market and has powerfull open embedded software ecosystem like MicroPython and Lua and even javascript.</small><br />
I took the Rust ESP32 tutorial's idea with building llvm+clang for xtensa and referenced the component integration with ESP-IDF(esp32 offical C SDK), and finally got a success.<br />
<br />
== Get the llvm and clang source for xtensa ==<br />
<br />
<syntaxhighlight lang="shell"><br />
$ git clone https://github.com/espressif/llvm-xtensa.git<br />
$ git clone https://github.com/espressif/clang-xtensa.git llvm-xtensa/tools/clang<br />
</syntaxhighlight><br />
<br />
== Building llvm-clang for xtensa ==<br />
<br />
<syntaxhighlight lang="shell"><br />
mkdir llvm_build<br />
cd llvm_build<br />
<br />
# from https://gist.github.com/MabezDev/26e175790f84f2f2b0f9bca4e63275d1<br />
cmake ../llvm-xtensa -DLLVM_TARGETS_TO_BUILD="Xtensa" -DCMAKE_BUILD_TYPE=Release -G "Ninja" -D CMAKE_INSTALL_PREFIX=/opt/llvm-xtensa<br />
<br />
# Take a while<br />
cmake --build . OR ninja<br />
ninja install<br />
</syntaxhighlight><br />
<br />
this should build the esp32 clang toolchain with Assemblly output(llvm-xtensa now can only generate AS output). and building a test c code will has these kind of error:<br />
<br />
<syntaxhighlight lang="shell"><br />
$ /opt/llvm-xtensa/bin/clang -target xtensa -c test.c<br />
/tmp/test-2191f8.s: Assembler messages:<br />
/tmp/test-2191f8.s:4: Error: unknown pseudo-op: `.literal'<br />
/tmp/test-2191f8.s:5: Error: unknown pseudo-op: `.literal'<br />
/tmp/test-2191f8.s:6: Error: unknown pseudo-op: `.literal'<br />
/tmp/test-2191f8.s:12: Error: no such instruction: `entry sp,40'<br />
/tmp/test-2191f8.s:13: Error: no such instruction: `mov.n a7,sp'<br />
/tmp/test-2191f8.s:14: Error: no such instruction: `l32r a8,.LCPI0_0'<br />
/tmp/test-2191f8.s:15: Error: no such instruction: `s32i.n a8,a7,4'<br />
/tmp/test-2191f8.s:16: Error: no such instruction: `l32i.n a11,a7,4'<br />
/tmp/test-2191f8.s:17: Error: no such instruction: `l32r a10,.LCPI0_1'<br />
/tmp/test-2191f8.s:18: Error: no such instruction: `l32r a8,.LCPI0_2'<br />
/tmp/test-2191f8.s:19: Error: no such instruction: `callx8 a8'<br />
/tmp/test-2191f8.s:20: Error: no such instruction: `s32i.n a10,a7,0'<br />
/tmp/test-2191f8.s:21: Error: no such instruction: `movsp sp,a7'<br />
/tmp/test-2191f8.s:22: Error: no such instruction: `retw.n'<br />
clang-6.0: error: assembler command failed with exit code 1 (use -v to see invocation)<br />
</syntaxhighlight><br />
<br />
but building .S output is working:<br />
<br />
<syntaxhighlight lang="shell"><br />
$ /opt/llvm-xtensa/bin/clang -target xtensa -S test.c -o test.S<br />
</syntaxhighlight><br />
<br />
Then we can use the as tool from ESP32 C toolchain to turn assemblly code to machine code:<br />
<br />
<syntaxhighlight lang="shell"><br />
$ xtensa-esp32-elf-as test.S -o test-c.o<br />
$ file test-c.o<br />
test-c.o: ELF 32-bit LSB relocatable, Tensilica Xtensa, version 1 (SYSV), not stripped<br />
</syntaxhighlight><br />
<br />
== Building ldc2 for esp32 from source using above xtensa llvm tool ==<br />
<br />
get ldc source, I just used ldc-1.19.0-beta1-src.tar.gz and untared to somewhere, then make the building:<br />
<br />
<syntaxhighlight lang="shell"><br />
mkdir build-ldc<br />
<br />
cmake -G Ninja ../ldc_source_dir -DCMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/opt/ldc-xtensa -DLLVM_ROOT_DIR=/opt/llvm-xtensa<br />
ninja ldc2<br />
</syntaxhighlight><br />
<br />
And you may experience this:<br />
<br />
<syntaxhighlight lang="shell"><br />
Linking CXX executable bin/ldc2<br />
FAILED: bin/ldc2 <br />
: && /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 && :<br />
lib/libldc.a(main.cpp.o):main.cpp:function cppmain(): error: undefined reference to 'llvm::initializeGlobalISel(llvm::PassRegistry&)'<br />
collect2: error: ld returned 1 exit status<br />
ninja: build stopped: subcommand failed.<br />
</syntaxhighlight><br />
<br />
I don't know why this error happens, but it's easy to fix it for the building:<br />
<br />
Edit '''build.ninja''' in your build-ldc dir, search ''build bin/ldc2:'' and edit '''LINK_LIBRARIES''' add ''-lLLVMGlobalISel'' before ''-lLLVMCodeGen''<br />
and type ''ninja ldc2'' again.<br />
<br />
Then we got ldc2 for xtensa in '''build-ldc/bin'''<br />
<br />
== Test ==<br />
<br />
edit some D betterC code:<br />
<br />
<syntaxhighlight lang="d"><br />
void d_func ()<br />
{<br />
int[4] arr;<br />
auto c = arr.length;<br />
}<br />
</syntaxhighlight><br />
<br />
and build the d code using command like this:<br />
<br />
<syntaxhighlight lang="shell"><br />
build-ldc2/bin/ldc2 -mtriple=xtensa-esp32-elf -mcpu=esp32 -gcc=xtensa-esp32-elf-gcc -betterC -dip1000 -boundscheck=off -linkonce-templates test.d -c<br />
<br />
$ file test.o<br />
test.o: ELF 32-bit LSB relocatable, Tensilica Xtensa, version 1 (SYSV), not stripped<br />
<br />
$ readelf -s test.o<br />
<br />
Symbol table '.symtab' contains 4 entries:<br />
Num: Value Size Type Bind Vis Ndx Name<br />
0: 00000000 0 NOTYPE LOCAL DEFAULT UND <br />
1: 00000000 0 FILE LOCAL DEFAULT ABS test.d<br />
2: 00000000 0 SECTION LOCAL DEFAULT 4 <br />
3: 00000000 24 FUNC GLOBAL DEFAULT 4 _D4test6d_funcFZv<br />
</syntaxhighlight><br />
<br />
You can put the long compiler command into a shell script:<br />
<br />
<syntaxhighlight lang="shell"><br />
$ cat xtensa-ldc<br />
#!/bin/sh<br />
<br />
export PATH=${HOME}/esp/xtensa-esp32-elf-5/bin:${PATH}<br />
build-ldc/bin/ldc2 -mtriple=xtensa-esp32-elf -mcpu=esp32 -gcc=xtensa-esp32-elf-gcc -betterC -dip1000 -boundscheck=off -linkonce-templates $@<br />
</syntaxhighlight><br />
<br />
ps: you can also edit ldc.conf to make all the options by default.<br />
<br />
== integrating with IDF as a component ==<br />
<br />
create a component dir called `dcode`, and write some makefile:<br />
<br />
<syntaxhighlight lang="Makefile"><br />
$ cat component.mk<br />
<br />
$(COMPONENT_LIBRARY):dcode.a<br />
<br />
SRC := $(wildcard $(COMPONENT_PATH)/*.d)<br />
COMOBJS := $(patsubst %.d, %.o, $(SRC))<br />
<br />
%.o : %.d<br />
ldc2-xtensa -c $< -of=$@<br />
<br />
COMPONENT_ADD_LDFLAGS += $(COMPONENT_BUILD_DIR)/dcodelib.a<br />
<br />
dcodelib :<br />
xtensa-esp32-elf-ar rc $(COMPONENT_BUILD_DIR)/dcodelib.a $(COMOBJS)<br />
<br />
dcode.a: $(SRC) $(COMOBJS) dcodelib<br />
</syntaxhighlight><br />
<br />
And you will have betterC d code compiles and linking:<br />
<br />
<syntaxhighlight lang="d"><br />
$ cat dcode.d<br />
<br />
module dcode;<br />
<br />
extern(C) int printf (scope const char * fmt, ...);<br />
<br />
char[8] a = ['a'];<br />
<br />
extern (C) void dlang_main()<br />
{<br />
uint i = 0;<br />
<br />
<br />
printf("hello, dlang says : i = %d, char a len = %d\r\n", i, a.length);<br />
}<br />
</syntaxhighlight><br />
<br />
Then, call dlang_main as a plain C function in any other place of your esp32 application, you should see that D is saying hello to you. ^_^</div>
Dangbinghoo
https://wiki.dlang.org/?title=Tutorials&diff=9715
Tutorials
2019-11-26T07:36:47Z
<p>Dangbinghoo: /* How To */</p>
<hr />
<div>== Videos Tutorials ==<br />
* [[Videos#Tutorials | Video tutorials]]<br />
<br />
== Best Practices ==<br />
* [[Order of import statements]]<br />
* [[Portability and performance]]<br />
* [[Conventional module name for importing all modules in a package]]<br />
<br />
== Common Idioms ==<br />
<br />
Although D inherited much of its syntax from C and C++, the new features that it introduces lead to some common idioms that are unique to D.<br />
See also category [[:Category:CommonIdiom|CommonIdiom]].<br />
<br />
* [[Initializing variables]]<br />
* [[Declaring constants]]<br />
* [[Looping over integers]]<br />
* [[Unittest#Placement|Unittest placement]]<br />
** [[Unittest#Unittest-specific imports and helper functions|Imports and helper functions only present when compiling with -unittest]]<br />
* [[Commenting out code]]<br />
* [[Dense multidimensional arrays|Declaring dense multidimensional arrays]]<br />
* [[Voldemort types]]<br />
<br />
== Design Patterns ==<br />
<br />
* [[Instantiator Function Pattern]] - Instantiating classes and structs with minimal redundancy.<br />
* [[Compile-time Command Pattern]] - Store function and arguments to be invoked later.<br />
* [[Higher Order Range Pattern]] - Transform a range before passing it to a function/object.<br />
* [[Mixin Macros Pattern]] - Mixins + Compile-Time Magic<br />
* [[Low-Lock Singleton Pattern]] - Singletons without double-checked locking<br />
<br />
== How To ==<br />
See also category [[:Category:HowTo|HowTo]].<br />
* [[Bind D to C]]<br />
* [[Compiling_and_linking_with_DMD_on_Windows|Compile and link with DMD on Windows]]<br />
* [[Linking_With_Unilink|Link with the Unilink linker on Windows instead of Optlink]]<br />
* [[Convert header files with SED]]<br />
* [[Defining custom print format specifiers|Define custom print format specifiers]]<br />
* [[Function literals]]<br />
* [[Implicit conversions in user types|Implicitly convert a user-defined type to a builtin type]]<br />
* [[Output locale character (MBS) to console]]<br />
* [[Promote D Projects]]<br />
* [[Regular expressions]]<br />
* [[Runtime type information (RTTI)]]<br />
* [[Run D in a CGI (web) environment]]<br />
* [[Tame OPTLINK]]<br />
* [[Unittest|Run unit tests]]<br />
* [[Using NASM with D]]<br />
* [[Read table data from file|Split file into multidimensional dynamic string array]]<br />
* [[Porting 32 Bit Code to 64 Bits]]<br />
* [[Converting C .h Files to D Modules]]<br />
* [[Instantiating Class Objects Elsewhere Than the GC Heap]]<br />
* [[Timing Code]]<br />
* [[Extending Unit Tests]]<br />
* [[Running DMD From The Command Prompt]]<br />
* [[Perf]]<br />
* [[Floating Point Gotchas]]<br />
* [[LDC+Dub+Vibe.d on SmartOS 64bit]]<br />
* [[Call D from Ruby using FFI]]<br />
* [[Programming in D tutorial on Embedded Linux ARM devices]]<br />
* [[D on esp32/esp8266(llvm-xtensa+ldc) and how to get started]]<br />
<br />
=== Microsoft Windows ===<br />
* [[D for Win32]]<br />
* [[Win32 DLLs in D]]<br />
* [[COM Programming]]<br />
* [[Using UTF on Windows]]<br />
<br />
[[Category:Tutorials]].</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9119
Programming in D tutorial on Embedded Linux ARM devices
2018-03-19T01:40:58Z
<p>Dangbinghoo: /* Preparing your ARM GCC toolchain */</p>
<hr />
<div>= Introduction =<br />
<br />
D is a great systems-programming language with clean syntax and great modelling power. Traditionally, Linux based embedded devices are programmed using C or C++. Python and Java are more popular today, but fail due to large runtime size and resource requirements. Programming in D will be comfortable, since it is like a dynamic language, but has native code performance, and has full ABI compatibility with C, making it very suitable as a “Linux systems-programming language”.<br />
<br />
This simple tutorial will introduce to programming in D on Embedded ARM Linux step by step.<br />
<br />
= Preparing your ARM GCC toolchain =<br />
<br />
The very first thing is to make your toolchain prepared. Although clang has supported ARM for a very long time, GCC is still the premier choice for compiling to ARM Linux systems.<br />
<br />
If you are a ARM Linux application programmer, you probably already have ARM GCC installed, and tested some hello world prgrams on your ARM board.<br />
<br />
However, if you haven't installed ARM GCC, it is quite easy.<br />
<br />
Arch Linux: <br />
<pre>$ pacman -S arm-linux-gnueabihf-gcc</pre><br />
Debian:<br />
<pre>$ apt install gcc-arm-linux-gnueabihf</pre><br />
Fedora:<br />
<pre>$ dnf install arm-linux-gnueabihf-{binutils,gcc,glibc}</pre><br />
<br />
''for Fedora or Redhat based os like Centos, if you found armhf toolchain is not quite easy to install, you can just install arm target instead of armhf using <code>$ yum install gcc-arm-linux-gnu </code>, and then using <code>arm-linux-gcc</code> rather than <code>arm-linux-gnueabihf-gcc</code>''<br />
<br />
After the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
Create a file, test.c, that contains the following, using your favorite text editor.<br />
<br />
<syntaxhighlight lang="D"><br />
#include <stdio.h><br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf("hello world! 3.14 * 2 = %f\n";, a*b);<br />
return 0;<br />
}<br />
<br />
</syntaxhighlight><br />
Then compile using:<br />
<pre>$ arm-linux-gnueabihf-gcc test.c -o test</pre><br />
Copy the compiled program to your ARM target board:<br />
<pre>$ scp test user@armboard:/home/user</pre><br />
<br />
On the ARM target run the test executable.<br />
<pre>ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
<div style="background:#ffd; padding: 0.5ex 0.5ex;"><br />
<span style="font-size: 1.4em; color: #ca4;">&#9888;</span>If your ARM GCC toolchain was compiled by yocto, you may need to call GCC using $CC after you sourced the environment setup script.<br />
</div><br />
<br />
= Installing LDC2 =<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and CPUs other than x86.<br />
<br />
GDC support for arm can be enabled if you are compiling your toolchain by yourself, by passing <code>–enable-languages=c,d,cpp</code> when configuring (i.e. <code>./configure -–enable-languages=c,d,cpp</code>. Or, you can download an ARM enabled GDC build from the [https://www.gdcproject.org/ GDC project home page].<br />
<br />
As of the writing of this tutorial, the latest GDC release (6.3.0) is not as good as LDC2, for ARM targets.<br />
<br />
LDC has better support for ARM targets, and is more actively developed that GDC. And, as it is based on LLVM, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
The recommended way to install LDC is by using the install script (works on POSIX and POSIX like systems):<br />
<pre>curl https://dlang.org/install.sh | bash -s ldc</pre><br />
<br />
You can also search your operating system's packages for the LDC package.<br />
<br />
Verify that LDC was installed correctly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointing, but don’t worry, we have ARM well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
= Compiling the D runtime for the ARM target =<br />
<br />
Before doing this, you need to make sure ,<code>cmake</code> is installed on your host. If not, please install it.<br />
Then, just type the commands bellow to compile your D runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After the build, you will get something like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is sitting in <code>ldc-build-runtime.tmp/lib</code> , the directory named <code>ldc-build-runtime.tmp</code> is temporary, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple alias for ease of use.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
where <code>${LDC2ARMRUNTIME}</code> is the runtime directory you prepared earlier.<br />
<br />
= The D hello world on ARM =<br />
<br />
With your favourite text editor, just like before with c, make a file called test.d with your favourite text editor. It should contain the following code:<br />
<syntaxhighlight lang="D"><br />
import std.stdio;<br />
void main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
writeln("hello world from D!";);<br />
writeln("3.14 * 2 = ", a * b);<br />
}<br />
</syntaxhighlight><br />
<br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable with the file name <code>testd</code> instead of the default, which would derive the name from the input file.<br />
<br />
Now, copy the testd file you just created to your arm target, and take a deep breath before executing it.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! We finally reach the point! Congratulations!<br />
<br />
= Letting Dub manage the project =<br />
<br />
For testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it. Edit the file <code>vibeex/dub.json</code> with your favourite text editor, changing the dependency version from <code>0.7.30</code> to <code>0.8.3</code>(This is the latest version when writting this tutorial). The file should look something like this:<br />
<syntaxhighlight lang="json"><br />
{<br />
"name": "vibeex",<br />
"authors": [<br />
"dbh"<br />
],<br />
"dependencies": {<br />
"vibe-d": "~>0.8.30"<br />
},<br />
"description": "A simple vibe.d server application.",<br />
"copyright": "Copyright © 2018, dbh",<br />
"license": "proprietary"<br />
}<br />
</syntaxhighlight><br />
<br />
when building using dub, the alias we created (ldc-arm) will not work. We need to turn this into a shell script adapter:<br />
<br />
<syntaxhighlight lang="sh">#!/bin/sh<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@<br />
</syntaxhighlight><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<syntaxhighlight lang="sh"><br />
$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@<br />
</syntaxhighlight><br />
<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
However, sometime we just get unlucky. If your toolchain does not have some library for the arm target present, dub will fail, with errors like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
<br />
This means that the library path does not include <code>libssl</code>, <code>libcrypto</code> and <code>libz</code>. You need to find or build a toolchain with the extra libraries built-in, or, just cross-compile the desired C library and install it to your toolchain's <code>sysroot</code> path.<br />
(The concept of toolchain sysroot can be referenced by [https://elinux.org/images/1/15/Anatomy_of_Cross-Compilation_Toolchains.pdf elinux.org Anatomy_of_Cross-Compilation_Toolchains-Page 21])<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@armhost:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@armhost:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
Yeah! we finally did it!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9118
Programming in D tutorial on Embedded Linux ARM devices
2018-03-19T01:32:22Z
<p>Dangbinghoo: /* Preparing your ARM GCC toolchain */</p>
<hr />
<div>= Introduction =<br />
<br />
D is a great systems-programming language with clean syntax and great modelling power. Traditionally, Linux based embedded devices are programmed using C or C++. Python and Java are more popular today, but fail due to large runtime size and resource requirements. Programming in D will be comfortable, since it is like a dynamic language, but has native code performance, and has full ABI compatibility with C, making it very suitable as a “Linux systems-programming language”.<br />
<br />
This simple tutorial will introduce to programming in D on Embedded ARM Linux step by step.<br />
<br />
= Preparing your ARM GCC toolchain =<br />
<br />
The very first thing is to make your toolchain prepared. Although clang has supported ARM for a very long time, GCC is still the premier choice for compiling to ARM Linux systems.<br />
<br />
If you are a ARM Linux application programmer, you probably already have ARM GCC installed, and tested some hello world prgrams on your ARM board.<br />
<br />
However, if you haven't installed ARM GCC, it is quite easy.<br />
<br />
Arch Linux: <br />
<pre>$ pacman -S arm-linux-gnueabihf-gcc</pre><br />
Debian:<br />
<pre>$ apt install gcc-arm-linux-gnueabihf</pre><br />
Fedora or CentOS:<br />
<pre>$ dnf install arm-linux-gnueabihf-{binutils,gcc,glibc}</pre><br />
<br />
After the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
Create a file, test.c, that contains the following, using your favourite text editor.<br />
<br />
<syntaxhighlight lang="D"><br />
#include <stdio.h><br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf("hello world! 3.14 * 2 = %f\n";, a*b);<br />
return 0;<br />
}<br />
<br />
</syntaxhighlight><br />
Then compile using:<br />
<pre>$ arm-linux-gnueabihf-gcc test.c -o test</pre><br />
Copy the compiled program to your ARM target board:<br />
<pre>$ scp test user@armboard:/home/user</pre><br />
<br />
On the ARM target run the test executable.<br />
<pre>ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
<div style="background:#ffd; padding: 0.5ex 0.5ex;"><br />
<span style="font-size: 1.4em; color: #ca4;">&#9888;</span>If your ARM GCC toolchain was compiled by yocto, you may need to call GCC using $CC after you sourced the environment setup script.<br />
</div><br />
<br />
= Installing LDC2 =<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and CPUs other than x86.<br />
<br />
GDC support for arm can be enabled if you are compiling your toolchain by yourself, by passing <code>–enable-languages=c,d,cpp</code> when configuring (i.e. <code>./configure -–enable-languages=c,d,cpp</code>. Or, you can download an ARM enabled GDC build from the [https://www.gdcproject.org/ GDC project home page].<br />
<br />
As of the writing of this tutorial, the latest GDC release (6.3.0) is not as good as LDC2, for ARM targets.<br />
<br />
LDC has better support for ARM targets, and is more actively developed that GDC. And, as it is based on LLVM, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
The recommended way to install LDC is by using the install script (works on POSIX and POSIX like systems):<br />
<pre>curl https://dlang.org/install.sh | bash -s ldc</pre><br />
<br />
You can also search your operating system's packages for the LDC package.<br />
<br />
Verify that LDC was installed correctly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointing, but don’t worry, we have ARM well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
= Compiling the D runtime for the ARM target =<br />
<br />
Before doing this, you need to make sure ,<code>cmake</code> is installed on your host. If not, please install it.<br />
Then, just type the commands bellow to compile your D runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After the build, you will get something like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is sitting in <code>ldc-build-runtime.tmp/lib</code> , the directory named <code>ldc-build-runtime.tmp</code> is temporary, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple alias for ease of use.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
where <code>${LDC2ARMRUNTIME}</code> is the runtime directory you prepared earlier.<br />
<br />
= The D hello world on ARM =<br />
<br />
With your favourite text editor, just like before with c, make a file called test.d with your favourite text editor. It should contain the following code:<br />
<syntaxhighlight lang="D"><br />
import std.stdio;<br />
void main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
writeln("hello world from D!";);<br />
writeln("3.14 * 2 = ", a * b);<br />
}<br />
</syntaxhighlight><br />
<br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable with the file name <code>testd</code> instead of the default, which would derive the name from the input file.<br />
<br />
Now, copy the testd file you just created to your arm target, and take a deep breath before executing it.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! We finally reach the point! Congratulations!<br />
<br />
= Letting Dub manage the project =<br />
<br />
For testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it. Edit the file <code>vibeex/dub.json</code> with your favourite text editor, changing the dependency version from <code>0.7.30</code> to <code>0.8.3</code>(This is the latest version when writting this tutorial). The file should look something like this:<br />
<syntaxhighlight lang="json"><br />
{<br />
"name": "vibeex",<br />
"authors": [<br />
"dbh"<br />
],<br />
"dependencies": {<br />
"vibe-d": "~>0.8.30"<br />
},<br />
"description": "A simple vibe.d server application.",<br />
"copyright": "Copyright © 2018, dbh",<br />
"license": "proprietary"<br />
}<br />
</syntaxhighlight><br />
<br />
when building using dub, the alias we created (ldc-arm) will not work. We need to turn this into a shell script adapter:<br />
<br />
<syntaxhighlight lang="sh">#!/bin/sh<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@<br />
</syntaxhighlight><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<syntaxhighlight lang="sh"><br />
$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@<br />
</syntaxhighlight><br />
<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
However, sometime we just get unlucky. If your toolchain does not have some library for the arm target present, dub will fail, with errors like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
<br />
This means that the library path does not include <code>libssl</code>, <code>libcrypto</code> and <code>libz</code>. You need to find or build a toolchain with the extra libraries built-in, or, just cross-compile the desired C library and install it to your toolchain's <code>sysroot</code> path.<br />
(The concept of toolchain sysroot can be referenced by [https://elinux.org/images/1/15/Anatomy_of_Cross-Compilation_Toolchains.pdf elinux.org Anatomy_of_Cross-Compilation_Toolchains-Page 21])<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@armhost:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@armhost:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
Yeah! we finally did it!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9117
Programming in D tutorial on Embedded Linux ARM devices
2018-03-19T01:21:02Z
<p>Dangbinghoo: /* Letting Dub manage the project */</p>
<hr />
<div>= Introduction =<br />
<br />
D is a great systems-programming language with clean syntax and great modelling power. Traditionally, Linux based embedded devices are programmed using C or C++. Python and Java are more popular today, but fail due to large runtime size and resource requirements. Programming in D will be comfortable, since it is like a dynamic language, but has native code performance, and has full ABI compatibility with C, making it very suitable as a “Linux systems-programming language”.<br />
<br />
This simple tutorial will introduce to programming in D on Embedded ARM Linux step by step.<br />
<br />
= Preparing your ARM GCC toolchain =<br />
<br />
The very first thing is to make your toolchain prepared. Although clang has supported ARM for a very long time, GCC is still the premier choice for compiling to ARM Linux systems.<br />
<br />
If you are a ARM Linux application programmer, you probably already have ARM GCC installed, and tested some hello world prgrams on your ARM board.<br />
<br />
However, if you haven't installed ARM GCC, it is quite easy.<br />
<br />
Arch Linux: <br />
<pre>$ pacman -S arm-linux-gnueabihf-gcc</pre><br />
Debian:<br />
<pre>$ apt install gcc-arm-linux-gnueabihf</pre><br />
Fedora or CentOS:<br />
<pre>$ yum install gcc-arm-linux-gnu</pre><br />
<br />
After the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
Create a file, test.c, that contains the following, using your favourite text editor.<br />
<br />
<syntaxhighlight lang="D"><br />
#include <stdio.h><br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf("hello world! 3.14 * 2 = %f\n";, a*b);<br />
return 0;<br />
}<br />
<br />
</syntaxhighlight><br />
Then compile using:<br />
<pre>$ arm-linux-gnueabihf-gcc test.c -o test</pre><br />
Copy the compiled program to your ARM target board:<br />
<pre>$ scp test user@armboard:/home/user</pre><br />
<br />
On the ARM target run the test executable.<br />
<pre>ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
<div style="background:#ffd; padding: 0.5ex 0.5ex;"><br />
<span style="font-size: 1.4em; color: #ca4;">&#9888;</span>If your ARM GCC toolchain was compiled by yocto, you may need to call GCC using $CC after you sourced the environment setup script.<br />
</div><br />
<br />
= Installing LDC2 =<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and CPUs other than x86.<br />
<br />
GDC support for arm can be enabled if you are compiling your toolchain by yourself, by passing <code>–enable-languages=c,d,cpp</code> when configuring (i.e. <code>./configure -–enable-languages=c,d,cpp</code>. Or, you can download an ARM enabled GDC build from the [https://www.gdcproject.org/ GDC project home page].<br />
<br />
As of the writing of this tutorial, the latest GDC release (6.3.0) is not as good as LDC2, for ARM targets.<br />
<br />
LDC has better support for ARM targets, and is more actively developed that GDC. And, as it is based on LLVM, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
The recommended way to install LDC is by using the install script (works on POSIX and POSIX like systems):<br />
<pre>curl https://dlang.org/install.sh | bash -s ldc</pre><br />
<br />
You can also search your operating system's packages for the LDC package.<br />
<br />
Verify that LDC was installed correctly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointing, but don’t worry, we have ARM well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
= Compiling the D runtime for the ARM target =<br />
<br />
Before doing this, you need to make sure ,<code>cmake</code> is installed on your host. If not, please install it.<br />
Then, just type the commands bellow to compile your D runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After the build, you will get something like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is sitting in <code>ldc-build-runtime.tmp/lib</code> , the directory named <code>ldc-build-runtime.tmp</code> is temporary, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple alias for ease of use.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
where <code>${LDC2ARMRUNTIME}</code> is the runtime directory you prepared earlier.<br />
<br />
= The D hello world on ARM =<br />
<br />
With your favourite text editor, just like before with c, make a file called test.d with your favourite text editor. It should contain the following code:<br />
<syntaxhighlight lang="D"><br />
import std.stdio;<br />
void main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
writeln("hello world from D!";);<br />
writeln("3.14 * 2 = ", a * b);<br />
}<br />
</syntaxhighlight><br />
<br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable with the file name <code>testd</code> instead of the default, which would derive the name from the input file.<br />
<br />
Now, copy the testd file you just created to your arm target, and take a deep breath before executing it.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! We finally reach the point! Congratulations!<br />
<br />
= Letting Dub manage the project =<br />
<br />
For testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it. Edit the file <code>vibeex/dub.json</code> with your favourite text editor, changing the dependency version from <code>0.7.30</code> to <code>0.8.3</code>(This is the latest version when writting this tutorial). The file should look something like this:<br />
<syntaxhighlight lang="json"><br />
{<br />
"name": "vibeex",<br />
"authors": [<br />
"dbh"<br />
],<br />
"dependencies": {<br />
"vibe-d": "~>0.8.30"<br />
},<br />
"description": "A simple vibe.d server application.",<br />
"copyright": "Copyright © 2018, dbh",<br />
"license": "proprietary"<br />
}<br />
</syntaxhighlight><br />
<br />
when building using dub, the alias we created (ldc-arm) will not work. We need to turn this into a shell script adapter:<br />
<br />
<syntaxhighlight lang="sh">#!/bin/sh<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@<br />
</syntaxhighlight><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<syntaxhighlight lang="sh"><br />
$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@<br />
</syntaxhighlight><br />
<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
However, sometime we just get unlucky. If your toolchain does not have some library for the arm target present, dub will fail, with errors like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
<br />
This means that the library path does not include <code>libssl</code>, <code>libcrypto</code> and <code>libz</code>. You need to find or build a toolchain with the extra libraries built-in, or, just cross-compile the desired C library and install it to your toolchain's <code>sysroot</code> path.<br />
(The concept of toolchain sysroot can be referenced by [https://elinux.org/images/1/15/Anatomy_of_Cross-Compilation_Toolchains.pdf elinux.org Anatomy_of_Cross-Compilation_Toolchains-Page 21])<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@armhost:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@armhost:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
Yeah! we finally did it!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9116
Programming in D tutorial on Embedded Linux ARM devices
2018-03-19T01:04:36Z
<p>Dangbinghoo: /* Preparing your ARM GCC toolchain */</p>
<hr />
<div>= Introduction =<br />
<br />
D is a great systems-programming language with clean syntax and great modelling power. Traditionally, Linux based embedded devices are programmed using C or C++. Python and Java are more popular today, but fail due to large runtime size and resource requirements. Programming in D will be comfortable, since it is like a dynamic language, but has native code performance, and has full ABI compatibility with C, making it very suitable as a “Linux systems-programming language”.<br />
<br />
This simple tutorial will introduce to programming in D on Embedded ARM Linux step by step.<br />
<br />
= Preparing your ARM GCC toolchain =<br />
<br />
The very first thing is to make your toolchain prepared. Although clang has supported ARM for a very long time, GCC is still the premier choice for compiling to ARM Linux systems.<br />
<br />
If you are a ARM Linux application programmer, you probably already have ARM GCC installed, and tested some hello world prgrams on your ARM board.<br />
<br />
However, if you haven't installed ARM GCC, it is quite easy.<br />
<br />
Arch Linux: <br />
<pre>$ pacman -S arm-linux-gnueabihf-gcc</pre><br />
Debian:<br />
<pre>$ apt install gcc-arm-linux-gnueabihf</pre><br />
Fedora or CentOS:<br />
<pre>$ yum install gcc-arm-linux-gnu</pre><br />
<br />
After the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
Create a file, test.c, that contains the following, using your favourite text editor.<br />
<br />
<syntaxhighlight lang="D"><br />
#include <stdio.h><br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf("hello world! 3.14 * 2 = %f\n";, a*b);<br />
return 0;<br />
}<br />
<br />
</syntaxhighlight><br />
Then compile using:<br />
<pre>$ arm-linux-gnueabihf-gcc test.c -o test</pre><br />
Copy the compiled program to your ARM target board:<br />
<pre>$ scp test user@armboard:/home/user</pre><br />
<br />
On the ARM target run the test executable.<br />
<pre>ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
<div style="background:#ffd; padding: 0.5ex 0.5ex;"><br />
<span style="font-size: 1.4em; color: #ca4;">&#9888;</span>If your ARM GCC toolchain was compiled by yocto, you may need to call GCC using $CC after you sourced the environment setup script.<br />
</div><br />
<br />
= Installing LDC2 =<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and CPUs other than x86.<br />
<br />
GDC support for arm can be enabled if you are compiling your toolchain by yourself, by passing <code>–enable-languages=c,d,cpp</code> when configuring (i.e. <code>./configure -–enable-languages=c,d,cpp</code>. Or, you can download an ARM enabled GDC build from the [https://www.gdcproject.org/ GDC project home page].<br />
<br />
As of the writing of this tutorial, the latest GDC release (6.3.0) is not as good as LDC2, for ARM targets.<br />
<br />
LDC has better support for ARM targets, and is more actively developed that GDC. And, as it is based on LLVM, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
The recommended way to install LDC is by using the install script (works on POSIX and POSIX like systems):<br />
<pre>curl https://dlang.org/install.sh | bash -s ldc</pre><br />
<br />
You can also search your operating system's packages for the LDC package.<br />
<br />
Verify that LDC was installed correctly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointing, but don’t worry, we have ARM well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
= Compiling the D runtime for the ARM target =<br />
<br />
Before doing this, you need to make sure ,<code>cmake</code> is installed on your host. If not, please install it.<br />
Then, just type the commands bellow to compile your D runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After the build, you will get something like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is sitting in <code>ldc-build-runtime.tmp/lib</code> , the directory named <code>ldc-build-runtime.tmp</code> is temporary, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple alias for ease of use.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
where <code>${LDC2ARMRUNTIME}</code> is the runtime directory you prepared earlier.<br />
<br />
= The D hello world on ARM =<br />
<br />
With your favourite text editor, just like before with c, make a file called test.d with your favourite text editor. It should contain the following code:<br />
<syntaxhighlight lang="D"><br />
import std.stdio;<br />
void main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
writeln("hello world from D!";);<br />
writeln("3.14 * 2 = ", a * b);<br />
}<br />
</syntaxhighlight><br />
<br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable with the file name <code>testd</code> instead of the default, which would derive the name from the input file.<br />
<br />
Now, copy the testd file you just created to your arm target, and take a deep breath before executing it.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! We finally reach the point! Congratulations!<br />
<br />
= Letting Dub manage the project =<br />
<br />
For testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it. Edit the file <code>vibeex/dub.json</code> with your favourite text editor, changing the dependency version from <code>0.7.30</code> to <code>0.8.3</code>(This is the latest version when writting this tutorial). The file should look something like this:<br />
<syntaxhighlight lang="json"><br />
{<br />
"name": "vibeex",<br />
"authors": [<br />
"dbh"<br />
],<br />
"dependencies": {<br />
"vibe-d": "~>0.8.30"<br />
},<br />
"description": "A simple vibe.d server application.",<br />
"copyright": "Copyright © 2018, dbh",<br />
"license": "proprietary"<br />
}<br />
</syntaxhighlight><br />
<br />
when building using dub, the alias we created (ldc-arm) will not work. We need to turn this into a shell script adapter:<br />
<br />
<syntaxhighlight lang="sh">#!/bin/sh<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@<br />
</syntaxhighlight><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<syntaxhighlight lang="sh"><br />
$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@<br />
</syntaxhighlight><br />
<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
However, sometime we just get unlucky. If your toolchain does not have some library for the arm target present, dub will fail, with errors like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
<br />
This means that the library path does not include <code>libssl</code>, <code>libcrypto</code> and <code>libz</code>. You need to find or build a toolchain with the extra libraries built-in, or, just cross-compile the desired C library and install it to your toolchain's <code>sysroot</code> path.<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@armhost:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@armhost:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
Yeah! we finally did it!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9115
Programming in D tutorial on Embedded Linux ARM devices
2018-03-19T00:47:22Z
<p>Dangbinghoo: /* Letting Dub manage the project */</p>
<hr />
<div>= Introduction =<br />
<br />
D is a great systems-programming language with clean syntax and great modelling power. Traditionally, Linux based embedded devices are programmed using C or C++. Python and Java are more popular today, but fail due to large runtime size and resource requirements. Programming in D will be comfortable, since it is like a dynamic language, but has native code performance, and has full ABI compatibility with C, making it very suitable as a “Linux systems-programming language”.<br />
<br />
This simple tutorial will introduce to programming in D on Embedded ARM Linux step by step.<br />
<br />
= Preparing your ARM GCC toolchain =<br />
<br />
The very first thing is to make your toolchain prepared. Although clang has supported ARM for a very long time, GCC is still the premier choice for compiling to ARM Linux systems.<br />
<br />
If you are a ARM Linux application programmer, you probably already have ARM GCC installed, and tested some hello world prgrams on your ARM board.<br />
<br />
However, if you haven't installed ARM GCC, it is quite easy.<br />
<br />
Arch Linux: <br />
<pre>$ pacman -S arm-linux-gnueabihf-gcc</pre><br />
Debian:<br />
<pre>$ apt install gcc-arm-linux-gnueabihf</pre><br />
<br />
After the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
Create a file, test.c, that contains the following, using your favourite text editor.<br />
<br />
<syntaxhighlight lang="D"><br />
#include <stdio.h><br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf("hello world! 3.14 * 2 = %f\n";, a*b);<br />
return 0;<br />
}<br />
<br />
</syntaxhighlight><br />
Then compile using:<br />
<pre>$ arm-linux-gnueabihf-gcc test.c -o test</pre><br />
Copy the compiled program to your ARM target board:<br />
<pre>$ scp test user@armboard:/home/user</pre><br />
<br />
On the ARM target run the test executable.<br />
<pre>ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
<div style="background:#ffd; padding: 0.5ex 0.5ex;"><br />
<span style="font-size: 1.4em; color: #ca4;">&#9888;</span>If your ARM GCC toolchain was compiled by yocto, you may need to call GCC using $CC after you sourced the environment setup script.<br />
</div><br />
<br />
= Installing LDC2 =<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and CPUs other than x86.<br />
<br />
GDC support for arm can be enabled if you are compiling your toolchain by yourself, by passing <code>–enable-languages=c,d,cpp</code> when configuring (i.e. <code>./configure -–enable-languages=c,d,cpp</code>. Or, you can download an ARM enabled GDC build from the [https://www.gdcproject.org/ GDC project home page].<br />
<br />
As of the writing of this tutorial, the latest GDC release (6.3.0) is not as good as LDC2, for ARM targets.<br />
<br />
LDC has better support for ARM targets, and is more actively developed that GDC. And, as it is based on LLVM, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
The recommended way to install LDC is by using the install script (works on POSIX and POSIX like systems):<br />
<pre>curl https://dlang.org/install.sh | bash -s ldc</pre><br />
<br />
You can also search your operating system's packages for the LDC package.<br />
<br />
Verify that LDC was installed correctly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointing, but don’t worry, we have ARM well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
= Compiling the D runtime for the ARM target =<br />
<br />
Before doing this, you need to make sure ,<code>cmake</code> is installed on your host. If not, please install it.<br />
Then, just type the commands bellow to compile your D runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After the build, you will get something like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is sitting in <code>ldc-build-runtime.tmp/lib</code> , the directory named <code>ldc-build-runtime.tmp</code> is temporary, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple alias for ease of use.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
where <code>${LDC2ARMRUNTIME}</code> is the runtime directory you prepared earlier.<br />
<br />
= The D hello world on ARM =<br />
<br />
With your favourite text editor, just like before with c, make a file called test.d with your favourite text editor. It should contain the following code:<br />
<syntaxhighlight lang="D"><br />
import std.stdio;<br />
void main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
writeln("hello world from D!";);<br />
writeln("3.14 * 2 = ", a * b);<br />
}<br />
</syntaxhighlight><br />
<br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable with the file name <code>testd</code> instead of the default, which would derive the name from the input file.<br />
<br />
Now, copy the testd file you just created to your arm target, and take a deep breath before executing it.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! We finally reach the point! Congratulations!<br />
<br />
= Letting Dub manage the project =<br />
<br />
For testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it. Edit the file <code>vibeex/dub.json</code> with your favourite text editor, changing the dependency version from <code>0.7.30</code> to <code>0.8.3</code>(This is the latest version when writting this tutorial). The file should look something like this:<br />
<syntaxhighlight lang="json"><br />
{<br />
"name": "vibeex",<br />
"authors": [<br />
"dbh"<br />
],<br />
"dependencies": {<br />
"vibe-d": "~>0.8.30"<br />
},<br />
"description": "A simple vibe.d server application.",<br />
"copyright": "Copyright © 2018, dbh",<br />
"license": "proprietary"<br />
}<br />
</syntaxhighlight><br />
<br />
when building using dub, the alias we created (ldc-arm) will not work. We need to turn this into a shell script adapter:<br />
<br />
<syntaxhighlight lang="sh">#!/bin/sh<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@<br />
</syntaxhighlight><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<syntaxhighlight lang="sh"><br />
$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@<br />
</syntaxhighlight><br />
<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
However, sometime we just get unlucky. If your toolchain does not have some library for the arm target present, dub will fail, with errors like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
<br />
This means that the library path does not include <code>libssl</code>, <code>libcrypto</code> and <code>libz</code>. You need to find or build a toolchain with the extra libraries built-in, or, just cross-compile the desired C library and install it to your toolchain's <code>sysroot</code> path.<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@armhost:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@armhost:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
Yeah! we finally did it!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9114
Programming in D tutorial on Embedded Linux ARM devices
2018-03-19T00:43:50Z
<p>Dangbinghoo: /* Letting Dub manage the project */</p>
<hr />
<div>= Introduction =<br />
<br />
D is a great systems-programming language with clean syntax and great modelling power. Traditionally, Linux based embedded devices are programmed using C or C++. Python and Java are more popular today, but fail due to large runtime size and resource requirements. Programming in D will be comfortable, since it is like a dynamic language, but has native code performance, and has full ABI compatibility with C, making it very suitable as a “Linux systems-programming language”.<br />
<br />
This simple tutorial will introduce to programming in D on Embedded ARM Linux step by step.<br />
<br />
= Preparing your ARM GCC toolchain =<br />
<br />
The very first thing is to make your toolchain prepared. Although clang has supported ARM for a very long time, GCC is still the premier choice for compiling to ARM Linux systems.<br />
<br />
If you are a ARM Linux application programmer, you probably already have ARM GCC installed, and tested some hello world prgrams on your ARM board.<br />
<br />
However, if you haven't installed ARM GCC, it is quite easy.<br />
<br />
Arch Linux: <br />
<pre>$ pacman -S arm-linux-gnueabihf-gcc</pre><br />
Debian:<br />
<pre>$ apt install gcc-arm-linux-gnueabihf</pre><br />
<br />
After the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
Create a file, test.c, that contains the following, using your favourite text editor.<br />
<br />
<syntaxhighlight lang="D"><br />
#include <stdio.h><br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf("hello world! 3.14 * 2 = %f\n";, a*b);<br />
return 0;<br />
}<br />
<br />
</syntaxhighlight><br />
Then compile using:<br />
<pre>$ arm-linux-gnueabihf-gcc test.c -o test</pre><br />
Copy the compiled program to your ARM target board:<br />
<pre>$ scp test user@armboard:/home/user</pre><br />
<br />
On the ARM target run the test executable.<br />
<pre>ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
<div style="background:#ffd; padding: 0.5ex 0.5ex;"><br />
<span style="font-size: 1.4em; color: #ca4;">&#9888;</span>If your ARM GCC toolchain was compiled by yocto, you may need to call GCC using $CC after you sourced the environment setup script.<br />
</div><br />
<br />
= Installing LDC2 =<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and CPUs other than x86.<br />
<br />
GDC support for arm can be enabled if you are compiling your toolchain by yourself, by passing <code>–enable-languages=c,d,cpp</code> when configuring (i.e. <code>./configure -–enable-languages=c,d,cpp</code>. Or, you can download an ARM enabled GDC build from the [https://www.gdcproject.org/ GDC project home page].<br />
<br />
As of the writing of this tutorial, the latest GDC release (6.3.0) is not as good as LDC2, for ARM targets.<br />
<br />
LDC has better support for ARM targets, and is more actively developed that GDC. And, as it is based on LLVM, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
The recommended way to install LDC is by using the install script (works on POSIX and POSIX like systems):<br />
<pre>curl https://dlang.org/install.sh | bash -s ldc</pre><br />
<br />
You can also search your operating system's packages for the LDC package.<br />
<br />
Verify that LDC was installed correctly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointing, but don’t worry, we have ARM well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
= Compiling the D runtime for the ARM target =<br />
<br />
Before doing this, you need to make sure ,<code>cmake</code> is installed on your host. If not, please install it.<br />
Then, just type the commands bellow to compile your D runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After the build, you will get something like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is sitting in <code>ldc-build-runtime.tmp/lib</code> , the directory named <code>ldc-build-runtime.tmp</code> is temporary, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple alias for ease of use.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
where <code>${LDC2ARMRUNTIME}</code> is the runtime directory you prepared earlier.<br />
<br />
= The D hello world on ARM =<br />
<br />
With your favourite text editor, just like before with c, make a file called test.d with your favourite text editor. It should contain the following code:<br />
<syntaxhighlight lang="D"><br />
import std.stdio;<br />
void main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
writeln("hello world from D!";);<br />
writeln("3.14 * 2 = ", a * b);<br />
}<br />
</syntaxhighlight><br />
<br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable with the file name <code>testd</code> instead of the default, which would derive the name from the input file.<br />
<br />
Now, copy the testd file you just created to your arm target, and take a deep breath before executing it.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! We finally reach the point! Congratulations!<br />
<br />
= Letting Dub manage the project =<br />
<br />
For testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it. Edit the file <code>vibeex/dub.json</code> with your favourite text editor, changing the dependency version from <code>0.7.30</code> to <code>0.8.3</code>(This is the latest version when writting this tutorial). The file should look something like this:<br />
<syntaxhighlight lang="json"><br />
{<br />
"name": "vibeex",<br />
"authors": [<br />
"dbh"<br />
],<br />
"dependencies": {<br />
"vibe-d": "~>0.8.30"<br />
},<br />
"description": "A simple vibe.d server application.",<br />
"copyright": "Copyright © 2018, dbh",<br />
"license": "proprietary"<br />
}<br />
</syntaxhighlight><br />
<br />
when building using dub, the alias we created (ldc-arm) will not work. We need to turn this into a shell script adapter:<br />
<br />
<syntaxhighlight lang="sh">#!/bin/sh<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@<br />
</syntaxhighlight><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<syntaxhighlight lang="sh"><br />
$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@<br />
</syntaxhighlight><br />
'''NOTE''': if your toolchain does not have some library for the arm target present, dub will fail, with errors like this:<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
However, sometime we just get unlucky, and end up with something like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
This means that the library path does not include <code>libssl</code>, <code>libcrypto</code> and <code>libz</code>. You need to find or build a toolchain with the extra libraries built-in, or, just cross-compile the desired C library and install it to your toolchain's <code>sysroot</code> path.<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@armhost:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@armhost:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
Yeah! we finally did it!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9113
Programming in D tutorial on Embedded Linux ARM devices
2018-03-19T00:41:38Z
<p>Dangbinghoo: /* Letting Dub manage the project */</p>
<hr />
<div>= Introduction =<br />
<br />
D is a great systems-programming language with clean syntax and great modelling power. Traditionally, Linux based embedded devices are programmed using C or C++. Python and Java are more popular today, but fail due to large runtime size and resource requirements. Programming in D will be comfortable, since it is like a dynamic language, but has native code performance, and has full ABI compatibility with C, making it very suitable as a “Linux systems-programming language”.<br />
<br />
This simple tutorial will introduce to programming in D on Embedded ARM Linux step by step.<br />
<br />
= Preparing your ARM GCC toolchain =<br />
<br />
The very first thing is to make your toolchain prepared. Although clang has supported ARM for a very long time, GCC is still the premier choice for compiling to ARM Linux systems.<br />
<br />
If you are a ARM Linux application programmer, you probably already have ARM GCC installed, and tested some hello world prgrams on your ARM board.<br />
<br />
However, if you haven't installed ARM GCC, it is quite easy.<br />
<br />
Arch Linux: <br />
<pre>$ pacman -S arm-linux-gnueabihf-gcc</pre><br />
Debian:<br />
<pre>$ apt install gcc-arm-linux-gnueabihf</pre><br />
<br />
After the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
Create a file, test.c, that contains the following, using your favourite text editor.<br />
<br />
<syntaxhighlight lang="D"><br />
#include <stdio.h><br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf("hello world! 3.14 * 2 = %f\n";, a*b);<br />
return 0;<br />
}<br />
<br />
</syntaxhighlight><br />
Then compile using:<br />
<pre>$ arm-linux-gnueabihf-gcc test.c -o test</pre><br />
Copy the compiled program to your ARM target board:<br />
<pre>$ scp test user@armboard:/home/user</pre><br />
<br />
On the ARM target run the test executable.<br />
<pre>ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
<div style="background:#ffd; padding: 0.5ex 0.5ex;"><br />
<span style="font-size: 1.4em; color: #ca4;">&#9888;</span>If your ARM GCC toolchain was compiled by yocto, you may need to call GCC using $CC after you sourced the environment setup script.<br />
</div><br />
<br />
= Installing LDC2 =<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and CPUs other than x86.<br />
<br />
GDC support for arm can be enabled if you are compiling your toolchain by yourself, by passing <code>–enable-languages=c,d,cpp</code> when configuring (i.e. <code>./configure -–enable-languages=c,d,cpp</code>. Or, you can download an ARM enabled GDC build from the [https://www.gdcproject.org/ GDC project home page].<br />
<br />
As of the writing of this tutorial, the latest GDC release (6.3.0) is not as good as LDC2, for ARM targets.<br />
<br />
LDC has better support for ARM targets, and is more actively developed that GDC. And, as it is based on LLVM, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
The recommended way to install LDC is by using the install script (works on POSIX and POSIX like systems):<br />
<pre>curl https://dlang.org/install.sh | bash -s ldc</pre><br />
<br />
You can also search your operating system's packages for the LDC package.<br />
<br />
Verify that LDC was installed correctly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointing, but don’t worry, we have ARM well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
= Compiling the D runtime for the ARM target =<br />
<br />
Before doing this, you need to make sure ,<code>cmake</code> is installed on your host. If not, please install it.<br />
Then, just type the commands bellow to compile your D runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After the build, you will get something like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is sitting in <code>ldc-build-runtime.tmp/lib</code> , the directory named <code>ldc-build-runtime.tmp</code> is temporary, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple alias for ease of use.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
where <code>${LDC2ARMRUNTIME}</code> is the runtime directory you prepared earlier.<br />
<br />
= The D hello world on ARM =<br />
<br />
With your favourite text editor, just like before with c, make a file called test.d with your favourite text editor. It should contain the following code:<br />
<syntaxhighlight lang="D"><br />
import std.stdio;<br />
void main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
writeln("hello world from D!";);<br />
writeln("3.14 * 2 = ", a * b);<br />
}<br />
</syntaxhighlight><br />
<br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable with the file name <code>testd</code> instead of the default, which would derive the name from the input file.<br />
<br />
Now, copy the testd file you just created to your arm target, and take a deep breath before executing it.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! We finally reach the point! Congratulations!<br />
<br />
= Letting Dub manage the project =<br />
<br />
For testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it. Edit the file <code>vibeex/dub.json</code> with your favourite text editor, changing the dependency version from <code>0.7.30</code> to <code>0.8.3</code>. The file should look something like this:<br />
<syntaxhighlight lang="json"><br />
{<br />
"name": "vibeex",<br />
"authors": [<br />
"dbh"<br />
],<br />
"dependencies": {<br />
"vibe-d": "~>0.8.30"<br />
},<br />
"description": "A simple vibe.d server application.",<br />
"copyright": "Copyright © 2018, dbh",<br />
"license": "proprietary"<br />
}<br />
</syntaxhighlight><br />
<br />
when building using dub, the alias we created (ldc-arm) will not work. We need to turn this into a shell script adapter:<br />
<br />
<syntaxhighlight lang="sh">#!/bin/sh<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@<br />
</syntaxhighlight><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<syntaxhighlight lang="sh"><br />
$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@<br />
</syntaxhighlight><br />
'''NOTE''': if your toolchain does not have some library for the arm target present, dub will fail, with errors like this:<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
However, sometime we just get unlucky, and end up with something like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
This means that the library path does not include <code>libssl</code>, <code>libcrypto</code> and <code>libz</code>. You need to find or build a toolchain with the extra libraries built-in, or, just cross-compile the desired C library and install it to your toolchain's <code>sysroot</code> path.<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@armhost:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@armhost:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
Yeah! we finally did it!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9112
Programming in D tutorial on Embedded Linux ARM devices
2018-03-19T00:39:57Z
<p>Dangbinghoo: /* Compiling the D runtime for the ARM target */</p>
<hr />
<div>= Introduction =<br />
<br />
D is a great systems-programming language with clean syntax and great modelling power. Traditionally, Linux based embedded devices are programmed using C or C++. Python and Java are more popular today, but fail due to large runtime size and resource requirements. Programming in D will be comfortable, since it is like a dynamic language, but has native code performance, and has full ABI compatibility with C, making it very suitable as a “Linux systems-programming language”.<br />
<br />
This simple tutorial will introduce to programming in D on Embedded ARM Linux step by step.<br />
<br />
= Preparing your ARM GCC toolchain =<br />
<br />
The very first thing is to make your toolchain prepared. Although clang has supported ARM for a very long time, GCC is still the premier choice for compiling to ARM Linux systems.<br />
<br />
If you are a ARM Linux application programmer, you probably already have ARM GCC installed, and tested some hello world prgrams on your ARM board.<br />
<br />
However, if you haven't installed ARM GCC, it is quite easy.<br />
<br />
Arch Linux: <br />
<pre>$ pacman -S arm-linux-gnueabihf-gcc</pre><br />
Debian:<br />
<pre>$ apt install gcc-arm-linux-gnueabihf</pre><br />
<br />
After the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
Create a file, test.c, that contains the following, using your favourite text editor.<br />
<br />
<syntaxhighlight lang="D"><br />
#include <stdio.h><br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf("hello world! 3.14 * 2 = %f\n";, a*b);<br />
return 0;<br />
}<br />
<br />
</syntaxhighlight><br />
Then compile using:<br />
<pre>$ arm-linux-gnueabihf-gcc test.c -o test</pre><br />
Copy the compiled program to your ARM target board:<br />
<pre>$ scp test user@armboard:/home/user</pre><br />
<br />
On the ARM target run the test executable.<br />
<pre>ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
<div style="background:#ffd; padding: 0.5ex 0.5ex;"><br />
<span style="font-size: 1.4em; color: #ca4;">&#9888;</span>If your ARM GCC toolchain was compiled by yocto, you may need to call GCC using $CC after you sourced the environment setup script.<br />
</div><br />
<br />
= Installing LDC2 =<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and CPUs other than x86.<br />
<br />
GDC support for arm can be enabled if you are compiling your toolchain by yourself, by passing <code>–enable-languages=c,d,cpp</code> when configuring (i.e. <code>./configure -–enable-languages=c,d,cpp</code>. Or, you can download an ARM enabled GDC build from the [https://www.gdcproject.org/ GDC project home page].<br />
<br />
As of the writing of this tutorial, the latest GDC release (6.3.0) is not as good as LDC2, for ARM targets.<br />
<br />
LDC has better support for ARM targets, and is more actively developed that GDC. And, as it is based on LLVM, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
The recommended way to install LDC is by using the install script (works on POSIX and POSIX like systems):<br />
<pre>curl https://dlang.org/install.sh | bash -s ldc</pre><br />
<br />
You can also search your operating system's packages for the LDC package.<br />
<br />
Verify that LDC was installed correctly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointing, but don’t worry, we have ARM well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
= Compiling the D runtime for the ARM target =<br />
<br />
Before doing this, you need to make sure ,<code>cmake</code> is installed on your host. If not, please install it.<br />
Then, just type the commands bellow to compile your D runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After the build, you will get something like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is sitting in <code>ldc-build-runtime.tmp/lib</code> , the directory named <code>ldc-build-runtime.tmp</code> is temporary, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple alias for ease of use.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
where <code>${LDC2ARMRUNTIME}</code> is the runtime directory you prepared earlier.<br />
<br />
= The D hello world on ARM =<br />
<br />
With your favourite text editor, just like before with c, make a file called test.d with your favourite text editor. It should contain the following code:<br />
<syntaxhighlight lang="D"><br />
import std.stdio;<br />
void main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
writeln("hello world from D!";);<br />
writeln("3.14 * 2 = ", a * b);<br />
}<br />
</syntaxhighlight><br />
<br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable with the file name <code>testd</code> instead of the default, which would derive the name from the input file.<br />
<br />
Now, copy the testd file you just created to your arm target, and take a deep breath before executing it.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! We finally reach the point! Congratulations!<br />
<br />
= Letting Dub manage the project =<br />
<br />
For testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/Changhong/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it. Edit the file <code>vibeex/dub.json</code> with your favourite text editor, changing the dependency version from <code>0.7.30</code> to <code>0.8.3</code>. The file should look something like this:<br />
<syntaxhighlight lang="json"><br />
{<br />
"name": "vibeex",<br />
"authors": [<br />
"dbh"<br />
],<br />
"dependencies": {<br />
"vibe-d": "~>0.8.30"<br />
},<br />
"description": "A simple vibe.d server application.",<br />
"copyright": "Copyright © 2018, dbh",<br />
"license": "proprietary"<br />
}<br />
</syntaxhighlight><br />
<br />
when building using dub, the alias we created (ldc-arm) will not work. We need to turn this into a shell script adapter:<br />
<br />
<syntaxhighlight lang="sh">#!/bin/sh<br />
LDC2ARMRUNTIME=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@<br />
</syntaxhighlight><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<syntaxhighlight lang="sh"><br />
$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@<br />
</syntaxhighlight><br />
'''NOTE''': if your toolchain does not have some library for the arm target present, dub will fail, with errors like this:<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
However, sometime we just get unlucky, and end up with something like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
This means that the library path does not include <code>libssl</code>, <code>libcrypto</code> and <code>libz</code>. You need to find or build a toolchain with the extra libraries built-in, or, just cross-compile the desired C library and install it to your toolchain's <code>sysroot</code> path.<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@armhost:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@armhost:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
Yeah! we finally did it!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9088
Programming in D tutorial on Embedded Linux ARM devices
2018-03-14T09:34:45Z
<p>Dangbinghoo: /* 6. the dub managed project */</p>
<hr />
<div>= Programming in D tutorial on Embedded Linux ARM devices =<br />
<br />
== 1. introductions ==<br />
<br />
D is a great system-programming language with clean syntax and modeling power. Traditionally, Linux based embedded devices is programmed using C or C++, even python is more populator today, it fails about its huge runtime size and resources requirements, and also java and many others. D programming will be comfortable like a dynamic language but has C native code running performance, and has full compatibility with C, making it very suitable as a “Linux system programming language”.<br />
<br />
This simple tutorial will introduce you how to programming in D on Embedded ARM Linux step by step.<br />
<br />
== 2. preparing your GCC ARM toolchain ==<br />
<br />
The very first thing is to make your arm gcc toolchain prepared. Although clang supports ARM for a very long time, GCC is still the first choice for compiling your ARM Linux system.<br />
<br />
If you are a arm linux application programmer, you would probably already have ARM GCC installed, and did a compiling and tested for your target board.<br />
<br />
However, install ARM GCC is quite easy, the following is the instructions to install arm toolchain<br />
<br />
<pre>ArchLinux : $ pacman -S arm-linux-gnueabihf-gcc<br />
Debain : $ apt install gcc-arm-linux-gnueabihf</pre><br />
after the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
<br />
<pre>$ vim test.c<br />
#include &lt;stdio.h&gt;<br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf(&quot;hello world! 3.14 * 2 = %f\n&quot;, a*b);<br />
return 0;<br />
}<br />
$ arm-linux-gnueabihf-gcc test.c -o test<br />
$ scp test user@armboard:/home/user<br />
<br />
# on ARM target run the test executable.<br />
ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
also, if your arm gcc is a toolchain compiled by yocto, you may calling GCC using $CC after you sourced the environment setup script.<br />
<br />
== 3. install the LDC2 D compiler ==<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and other cpus rother than x86 target.<br />
<br />
GDC support for arm can be enabled if you compiling your toolchain by yourself by passing –enable-languages=c,d,cpp when configuring. Or, you can download a arm GDC from GDC project home page.<br />
<br />
But at least when I am writing this tutorial, GDC only released 6.3.0 version which is not doing better support for the ARM target than LDC2 do.<br />
<br />
LDC has better support for ARM target, and is more actively developed that GDC. And, as based on LLVM architecture, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
So, what you need to download is right the LDC2 compiler for your x86 host.<br />
<br />
For better support for the D language, we recommend to download the latest LDC2 from github release page: https://github.com/ldc-developers/ldc/releases<br />
<br />
For ArchLinux or Gentoo Linux user, you can install the almost latest LDC compiler just using <code>pacman</code> or <code>emerge</code><br />
<br />
If you download LDC2 standalone release from github page, say: ['''ldc2-1.8.0-linux-x86_64.tar.xz'''](https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc2-1.8.0-linux-x86_64.tar.xz)<br />
<br />
we need a little bit tricky thing to do:<br />
<br />
<pre>mkdir your-devel-toolchain-dir<br />
tar xf ldc2-x.y.z-linux-x86_64.tar.xz -C your-devel-toolchain-dir</pre><br />
The compiler will be installed to a dir named <code>ldc2-1.8.0-linux-x86_64</code> which has it’s own bin , etc , lib sub directories. As it’s a standalone distribution, you need to add <code>ldc2-1.8.0-linux-x86_64/bin</code> to your PATH env.<br />
<br />
<pre>export PATH=${your-devel-toolchain-dir}/ldc2-1.8.0-linux-x86_64/bin:${PATH}</pre><br />
Now, you could invoke ldc2 directly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointed, but don’t worry, we have arm well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
== 4. compiling the D runtime for ARM target. ==<br />
<br />
before doing this, you need to make sure cmake is installed on your host.<br />
<br />
<pre>sudo apt install cmake</pre><br />
Then, just type the commands bellow to make your D arm runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After build, you will get result like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is right sit in <code>ldc-build-runtime.tmp/lib</code> , the dir name <code>ldc-build-runtime.tmp</code> is temp, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple custom command using alias for future comfortable.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
${LDC2ARMRUNTIME} is the runtime dir you just prepared before.<br />
<br />
== 5. the D hello world on ARM ! ==<br />
<br />
<pre>$ vim test.d<br />
import std.stdio;<br />
void main()<br />
{<br />
writeln(&quot;hello world from D!&quot;);<br />
writeln(&quot;3.14 * 2 = &quot;, 3.14*2);<br />
}</pre><br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable using <code>testd</code> filename rother than default <code>test</code>.<br />
<br />
Now, copy the testd to your arm target, type <code>./testd</code> and make a breath.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! we finally reach the point! Congratulations!<br />
<br />
== 6. the dub managed project ==<br />
<br />
For complex testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/Changhong/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it.<br />
<br />
<pre>$ vim vibeex/dub.json<br />
{<br />
&quot;name&quot;: &quot;vibeex&quot;,<br />
&quot;authors&quot;: [<br />
&quot;dbh&quot;<br />
],<br />
&quot;dependencies&quot;: {<br />
&quot;vibe-d&quot;: &quot;~&gt;0.7.30&quot;<br />
},<br />
&quot;description&quot;: &quot;A simple vibe.d server application.&quot;,<br />
&quot;copyright&quot;: &quot;Copyright © 2018, dbh&quot;,<br />
&quot;license&quot;: &quot;proprietary&quot;<br />
}</pre><br />
update 0.7.30 to 0.8.3.<br />
<br />
when building using dub, the alias method setup ldc-arm will not work. we need to turn this into a shell script adapter:<br />
<br />
<pre>#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@</pre><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<pre>$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@</pre><br />
'''NOTE''': if your toolchain does not have some library for the arm target present, dub will fail like this:<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
however, sometime we would have no luck, and got something like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
This means that all library path does not includes libssl, libcrypto, libz. You need to find or build a toolchain with extra lib built-in, or, just cross-compiling the desired c library and install to your toolchain sysroot path.<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@armhost:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@armhost:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
<br />
Yeah! we finally did that!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9087
Programming in D tutorial on Embedded Linux ARM devices
2018-03-14T09:34:20Z
<p>Dangbinghoo: /* 6. the dub managed project */</p>
<hr />
<div>= Programming in D tutorial on Embedded Linux ARM devices =<br />
<br />
== 1. introductions ==<br />
<br />
D is a great system-programming language with clean syntax and modeling power. Traditionally, Linux based embedded devices is programmed using C or C++, even python is more populator today, it fails about its huge runtime size and resources requirements, and also java and many others. D programming will be comfortable like a dynamic language but has C native code running performance, and has full compatibility with C, making it very suitable as a “Linux system programming language”.<br />
<br />
This simple tutorial will introduce you how to programming in D on Embedded ARM Linux step by step.<br />
<br />
== 2. preparing your GCC ARM toolchain ==<br />
<br />
The very first thing is to make your arm gcc toolchain prepared. Although clang supports ARM for a very long time, GCC is still the first choice for compiling your ARM Linux system.<br />
<br />
If you are a arm linux application programmer, you would probably already have ARM GCC installed, and did a compiling and tested for your target board.<br />
<br />
However, install ARM GCC is quite easy, the following is the instructions to install arm toolchain<br />
<br />
<pre>ArchLinux : $ pacman -S arm-linux-gnueabihf-gcc<br />
Debain : $ apt install gcc-arm-linux-gnueabihf</pre><br />
after the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
<br />
<pre>$ vim test.c<br />
#include &lt;stdio.h&gt;<br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf(&quot;hello world! 3.14 * 2 = %f\n&quot;, a*b);<br />
return 0;<br />
}<br />
$ arm-linux-gnueabihf-gcc test.c -o test<br />
$ scp test user@armboard:/home/user<br />
<br />
# on ARM target run the test executable.<br />
ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
also, if your arm gcc is a toolchain compiled by yocto, you may calling GCC using $CC after you sourced the environment setup script.<br />
<br />
== 3. install the LDC2 D compiler ==<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and other cpus rother than x86 target.<br />
<br />
GDC support for arm can be enabled if you compiling your toolchain by yourself by passing –enable-languages=c,d,cpp when configuring. Or, you can download a arm GDC from GDC project home page.<br />
<br />
But at least when I am writing this tutorial, GDC only released 6.3.0 version which is not doing better support for the ARM target than LDC2 do.<br />
<br />
LDC has better support for ARM target, and is more actively developed that GDC. And, as based on LLVM architecture, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
So, what you need to download is right the LDC2 compiler for your x86 host.<br />
<br />
For better support for the D language, we recommend to download the latest LDC2 from github release page: https://github.com/ldc-developers/ldc/releases<br />
<br />
For ArchLinux or Gentoo Linux user, you can install the almost latest LDC compiler just using <code>pacman</code> or <code>emerge</code><br />
<br />
If you download LDC2 standalone release from github page, say: ['''ldc2-1.8.0-linux-x86_64.tar.xz'''](https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc2-1.8.0-linux-x86_64.tar.xz)<br />
<br />
we need a little bit tricky thing to do:<br />
<br />
<pre>mkdir your-devel-toolchain-dir<br />
tar xf ldc2-x.y.z-linux-x86_64.tar.xz -C your-devel-toolchain-dir</pre><br />
The compiler will be installed to a dir named <code>ldc2-1.8.0-linux-x86_64</code> which has it’s own bin , etc , lib sub directories. As it’s a standalone distribution, you need to add <code>ldc2-1.8.0-linux-x86_64/bin</code> to your PATH env.<br />
<br />
<pre>export PATH=${your-devel-toolchain-dir}/ldc2-1.8.0-linux-x86_64/bin:${PATH}</pre><br />
Now, you could invoke ldc2 directly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointed, but don’t worry, we have arm well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
== 4. compiling the D runtime for ARM target. ==<br />
<br />
before doing this, you need to make sure cmake is installed on your host.<br />
<br />
<pre>sudo apt install cmake</pre><br />
Then, just type the commands bellow to make your D arm runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After build, you will get result like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is right sit in <code>ldc-build-runtime.tmp/lib</code> , the dir name <code>ldc-build-runtime.tmp</code> is temp, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple custom command using alias for future comfortable.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
${LDC2ARMRUNTIME} is the runtime dir you just prepared before.<br />
<br />
== 5. the D hello world on ARM ! ==<br />
<br />
<pre>$ vim test.d<br />
import std.stdio;<br />
void main()<br />
{<br />
writeln(&quot;hello world from D!&quot;);<br />
writeln(&quot;3.14 * 2 = &quot;, 3.14*2);<br />
}</pre><br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable using <code>testd</code> filename rother than default <code>test</code>.<br />
<br />
Now, copy the testd to your arm target, type <code>./testd</code> and make a breath.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! we finally reach the point! Congratulations!<br />
<br />
== 6. the dub managed project ==<br />
<br />
For complex testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/Changhong/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it.<br />
<br />
<pre>$ vim vibeex/dub.json<br />
{<br />
&quot;name&quot;: &quot;vibeex&quot;,<br />
&quot;authors&quot;: [<br />
&quot;dbh&quot;<br />
],<br />
&quot;dependencies&quot;: {<br />
&quot;vibe-d&quot;: &quot;~&gt;0.7.30&quot;<br />
},<br />
&quot;description&quot;: &quot;A simple vibe.d server application.&quot;,<br />
&quot;copyright&quot;: &quot;Copyright © 2018, dbh&quot;,<br />
&quot;license&quot;: &quot;proprietary&quot;<br />
}</pre><br />
update 0.7.30 to 0.8.3.<br />
<br />
when building using dub, the alias method setup ldc-arm will not work. we need to turn this into a shell script adapter:<br />
<br />
<pre>#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@</pre><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<pre>$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@</pre><br />
'''NOTE''': if your toolchain does not have some library for the arm target present, dub will fail like this:<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
however, sometime we would have no luck, and got something like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
This means that all library path does not includes libssl, libcrypto, libz. You need to find or build a toolchain with extra lib built-in, or, just cross-compiling the desired c library and install to your toolchain sysroot path.<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@armhost:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@chiot:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
<br />
Yeah! we finally did that!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9086
Programming in D tutorial on Embedded Linux ARM devices
2018-03-14T09:26:38Z
<p>Dangbinghoo: /* 3. install the LDC2 D compiler */</p>
<hr />
<div>= Programming in D tutorial on Embedded Linux ARM devices =<br />
<br />
== 1. introductions ==<br />
<br />
D is a great system-programming language with clean syntax and modeling power. Traditionally, Linux based embedded devices is programmed using C or C++, even python is more populator today, it fails about its huge runtime size and resources requirements, and also java and many others. D programming will be comfortable like a dynamic language but has C native code running performance, and has full compatibility with C, making it very suitable as a “Linux system programming language”.<br />
<br />
This simple tutorial will introduce you how to programming in D on Embedded ARM Linux step by step.<br />
<br />
== 2. preparing your GCC ARM toolchain ==<br />
<br />
The very first thing is to make your arm gcc toolchain prepared. Although clang supports ARM for a very long time, GCC is still the first choice for compiling your ARM Linux system.<br />
<br />
If you are a arm linux application programmer, you would probably already have ARM GCC installed, and did a compiling and tested for your target board.<br />
<br />
However, install ARM GCC is quite easy, the following is the instructions to install arm toolchain<br />
<br />
<pre>ArchLinux : $ pacman -S arm-linux-gnueabihf-gcc<br />
Debain : $ apt install gcc-arm-linux-gnueabihf</pre><br />
after the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
<br />
<pre>$ vim test.c<br />
#include &lt;stdio.h&gt;<br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf(&quot;hello world! 3.14 * 2 = %f\n&quot;, a*b);<br />
return 0;<br />
}<br />
$ arm-linux-gnueabihf-gcc test.c -o test<br />
$ scp test user@armboard:/home/user<br />
<br />
# on ARM target run the test executable.<br />
ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
also, if your arm gcc is a toolchain compiled by yocto, you may calling GCC using $CC after you sourced the environment setup script.<br />
<br />
== 3. install the LDC2 D compiler ==<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and other cpus rother than x86 target.<br />
<br />
GDC support for arm can be enabled if you compiling your toolchain by yourself by passing –enable-languages=c,d,cpp when configuring. Or, you can download a arm GDC from GDC project home page.<br />
<br />
But at least when I am writing this tutorial, GDC only released 6.3.0 version which is not doing better support for the ARM target than LDC2 do.<br />
<br />
LDC has better support for ARM target, and is more actively developed that GDC. And, as based on LLVM architecture, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
So, what you need to download is right the LDC2 compiler for your x86 host.<br />
<br />
For better support for the D language, we recommend to download the latest LDC2 from github release page: https://github.com/ldc-developers/ldc/releases<br />
<br />
For ArchLinux or Gentoo Linux user, you can install the almost latest LDC compiler just using <code>pacman</code> or <code>emerge</code><br />
<br />
If you download LDC2 standalone release from github page, say: ['''ldc2-1.8.0-linux-x86_64.tar.xz'''](https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc2-1.8.0-linux-x86_64.tar.xz)<br />
<br />
we need a little bit tricky thing to do:<br />
<br />
<pre>mkdir your-devel-toolchain-dir<br />
tar xf ldc2-x.y.z-linux-x86_64.tar.xz -C your-devel-toolchain-dir</pre><br />
The compiler will be installed to a dir named <code>ldc2-1.8.0-linux-x86_64</code> which has it’s own bin , etc , lib sub directories. As it’s a standalone distribution, you need to add <code>ldc2-1.8.0-linux-x86_64/bin</code> to your PATH env.<br />
<br />
<pre>export PATH=${your-devel-toolchain-dir}/ldc2-1.8.0-linux-x86_64/bin:${PATH}</pre><br />
Now, you could invoke ldc2 directly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointed, but don’t worry, we have arm well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
== 4. compiling the D runtime for ARM target. ==<br />
<br />
before doing this, you need to make sure cmake is installed on your host.<br />
<br />
<pre>sudo apt install cmake</pre><br />
Then, just type the commands bellow to make your D arm runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After build, you will get result like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is right sit in <code>ldc-build-runtime.tmp/lib</code> , the dir name <code>ldc-build-runtime.tmp</code> is temp, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple custom command using alias for future comfortable.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
${LDC2ARMRUNTIME} is the runtime dir you just prepared before.<br />
<br />
== 5. the D hello world on ARM ! ==<br />
<br />
<pre>$ vim test.d<br />
import std.stdio;<br />
void main()<br />
{<br />
writeln(&quot;hello world from D!&quot;);<br />
writeln(&quot;3.14 * 2 = &quot;, 3.14*2);<br />
}</pre><br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable using <code>testd</code> filename rother than default <code>test</code>.<br />
<br />
Now, copy the testd to your arm target, type <code>./testd</code> and make a breath.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! we finally reach the point! Congratulations!<br />
<br />
== 6. the dub managed project ==<br />
<br />
For complex testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/Changhong/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it.<br />
<br />
<pre>$ vim vibeex/dub.json<br />
{<br />
&quot;name&quot;: &quot;vibeex&quot;,<br />
&quot;authors&quot;: [<br />
&quot;dbh&quot;<br />
],<br />
&quot;dependencies&quot;: {<br />
&quot;vibe-d&quot;: &quot;~&gt;0.7.30&quot;<br />
},<br />
&quot;description&quot;: &quot;A simple vibe.d server application.&quot;,<br />
&quot;copyright&quot;: &quot;Copyright © 2018, dbh&quot;,<br />
&quot;license&quot;: &quot;proprietary&quot;<br />
}</pre><br />
update 0.7.30 to 0.8.3.<br />
<br />
when building using dub, the alias method setup ldc-arm will not work. we need to turn this into a shell script adapter:<br />
<br />
<pre>#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@</pre><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<pre>$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@</pre><br />
'''NOTE''': if your toolchain does not have some library for the arm target present, dub will fail like this:<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
however, sometime we would have no luck, and got something like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
This means that all library path does not includes libssl, libcrypto, libz. You need to find or build a toolchain with extra lib built-in, or, just cross-compiling the desired c library and install to your toolchain sysroot path.<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@chiot:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@chiot:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
<br />
Yeah! we finally did that!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Programming_in_D_tutorial_on_Embedded_Linux_ARM_devices&diff=9085
Programming in D tutorial on Embedded Linux ARM devices
2018-03-14T09:23:25Z
<p>Dangbinghoo: Created page with "= Programming in D tutorial on Embedded Linux ARM devices = == 1. introductions == D is a great system-programming language with clean syntax and modeling power. Traditional..."</p>
<hr />
<div>= Programming in D tutorial on Embedded Linux ARM devices =<br />
<br />
== 1. introductions ==<br />
<br />
D is a great system-programming language with clean syntax and modeling power. Traditionally, Linux based embedded devices is programmed using C or C++, even python is more populator today, it fails about its huge runtime size and resources requirements, and also java and many others. D programming will be comfortable like a dynamic language but has C native code running performance, and has full compatibility with C, making it very suitable as a “Linux system programming language”.<br />
<br />
This simple tutorial will introduce you how to programming in D on Embedded ARM Linux step by step.<br />
<br />
== 2. preparing your GCC ARM toolchain ==<br />
<br />
The very first thing is to make your arm gcc toolchain prepared. Although clang supports ARM for a very long time, GCC is still the first choice for compiling your ARM Linux system.<br />
<br />
If you are a arm linux application programmer, you would probably already have ARM GCC installed, and did a compiling and tested for your target board.<br />
<br />
However, install ARM GCC is quite easy, the following is the instructions to install arm toolchain<br />
<br />
<pre>ArchLinux : $ pacman -S arm-linux-gnueabihf-gcc<br />
Debain : $ apt install gcc-arm-linux-gnueabihf</pre><br />
after the toolchain installed, you need to make a simple test make sure that ARM GCC is generating arm executable properly.<br />
<br />
<pre>$ vim test.c<br />
#include &lt;stdio.h&gt;<br />
int main()<br />
{<br />
float a = 3.14;<br />
int b = 2;<br />
printf(&quot;hello world! 3.14 * 2 = %f\n&quot;, a*b);<br />
return 0;<br />
}<br />
$ arm-linux-gnueabihf-gcc test.c -o test<br />
$ scp test user@armboard:/home/user<br />
<br />
# on ARM target run the test executable.<br />
ARM $ ./test<br />
hello world! 3.14*2 = 6.280000<br />
</pre><br />
also, if your arm gcc is a toolchain compiled by yocto, you may calling GCC using $CC after you sourced the environment setup script.<br />
<br />
== 3. install the LDC2 D compiler ==<br />
<br />
D has 3 compiler implementations. Currently, only GDC and LDC support ARM and other cpus rother than x86 target.<br />
<br />
GDC support for arm can be enabled if you compiling your toolchain by yourself by passing –enable-languages=c,d,cpp when configuring. Or, you can download a arm GDC from GDC project home page.<br />
<br />
But at least when I am writing this tutorial, GDC only released 6.3.0 version which is not doing better support for the ARM target than LDC2 do.<br />
<br />
LDC has better support for ARM target, and is more actively developed that GDC. And, as based on LLVM architecture, LDC does not need a cross-compiling toolchain prepared for an individual target.<br />
<br />
So, what you need to download is right the LDC2 compiler for your x86 host.<br />
<br />
For better support for the D language, we recommend to download the latest LDC2 from github release page: https://github.com/ldc-developers/ldc/releases<br />
<br />
For ArchLinux or Gentoo Linux user, you can install the almost latest LDC compiler just using <code>pacman</code> or <code>emerge</code><br />
<br />
If you download LDC2 standalone release from github page, say: ['''ldc2-1.8.0-linux-x86_64.tar.xz'''](https://github.com/ldc-develo<br />
<br />
we need a little bit tricky thing to do:<br />
<br />
<pre>mkdir your-devel-toolchain-dir<br />
tar xf ldc2-x.y.z-linux-x86_64.tar.xz -C your-devel-toolchain-dir</pre><br />
The compiler will be installed to a dir named <code>ldc2-1.8.0-linux-x86_64</code> which has it’s own bin , etc , lib sub directories. As it’s a standalone distribution, you need to add <code>ldc2-1.8.0-linux-x86_64/bin</code> to your PATH env.<br />
<br />
<pre>export PATH=${your-devel-toolchain-dir}/ldc2-1.8.0-linux-x86_64/bin:${PATH}</pre><br />
Now, you could invoke ldc2 directly:<br />
<br />
<pre>$ ldc2 --version<br />
LDC - the LLVM D compiler (1.8.0):<br />
based on DMD v2.078.3 and LLVM 5.0.1<br />
built with LDC - the LLVM D compiler (1.8.0)<br />
Default target: x86_64-unknown-linux-gnu<br />
Host CPU: skylake<br />
http://dlang.org - http://wiki.dlang.org/LDC<br />
<br />
Registered Targets:<br />
aarch64 - AArch64 (little endian)<br />
aarch64_be - AArch64 (big endian)<br />
arm - ARM<br />
arm64 - ARM64 (little endian)<br />
......</pre><br />
As you can see from the ldc2 version output, arm64 is a registered target, but it’s not completely supported right now. It’s a little bit disappointed, but don’t worry, we have arm well supported when the target is gcc+glibc+linux. And ARM and ARMhf executable can directly run on an arm64 target when arm64 has multilib support.<br />
<br />
== 4. compiling the D runtime for ARM target. ==<br />
<br />
before doing this, you need to make sure cmake is installed on your host.<br />
<br />
<pre>sudo apt install cmake</pre><br />
Then, just type the commands bellow to make your D arm runtime:<br />
<br />
<pre>$ CC=arm-linux-gnueabihf-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-linux-gnueabihf&quot; --targetSystem=&quot;Linux;UNIX&quot;<br />
-------------------------------------------------------------------<br />
Creating build directory: ldc-build-runtime.tmp<br />
Downloading LDC source archive: https://github.com/ldc-developers/ldc/releases/download/v1.8.0/ldc-1.8.0-src.zip<br />
Invoking: [&quot;cmake&quot;, &quot;-DLDC_EXE_FULL=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2-1.8.0-linux-x86_64/bin/ldc2&quot;, &quot;-DD_VERSION=2&quot;, &quot;-DDMDFE_MINOR_VERSION=0&quot;, &quot;-DDMDFE_PATCH_VERSION=78&quot;, &quot;-DLDC_TARGET_PRESET=&quot;, &quot;-DTARGET_SYSTEM=Linux;UNIX&quot;, &quot;-DD_FLAGS=-w;-mtriple=arm-linux-gnueabihf&quot;, &quot;-DRT_CFLAGS=&quot;, &quot;-DLD_FLAGS=&quot;, &quot;/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime/ldc-build-runtime.tmp/ldc-src/runtime&quot;]<br />
......</pre><br />
The ldc-build-runtime tool will download ldc compiler source and making the build.<br />
<br />
'''''NOTE:''''' ''yocto built toolchain need to use a different manner:''<br />
<br />
<pre>CC=arm-poky-linux-gnueabi-gcc ldc-build-runtime --dFlags=&quot;-w;-mtriple=arm-poky-linux-gnueabi;-float-abi=hard;-mcpu=cortex-a7&quot; --targetSystem=&quot;Linux;UNIX&quot;</pre><br />
''for yocto toolchain the above arm-poky-linux-gnueabi-gcc is just a shell script adapter.''<br />
<br />
<pre>export SDKTARGETSYSROOT=your-target-root-fs-dir<br />
${POKYGCCBINPATH}/arm-poky-linux-gnueabi-gcc -march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=$SDKTARGETSYSROOT $@</pre><br />
After build, you will get result like bellow:<br />
<br />
<pre>$ ls <br />
ldc-build-runtime.tmp<br />
$ ls ldc-build-runtime.tmp/<br />
CMakeCache.txt cmake_install.cmake ldc-src lib objects objects-debug-shared<br />
CMakeFiles dummy.c ldc-src.zip Makefile objects-debug objects-shared</pre><br />
The runtime lib is right sit in <code>ldc-build-runtime.tmp/lib</code> , the dir name <code>ldc-build-runtime.tmp</code> is temp, you can rename it to a <code>ldc_arm_runtime</code> or something you like.<br />
<br />
Then, we will make a simple custom command using alias for future comfortable.<br />
<br />
<pre>alias ldcarm='ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib'</pre><br />
${LDC2ARMRUNTIME} is the runtime dir you just prepared before.<br />
<br />
== 5. the D hello world on ARM ! ==<br />
<br />
<pre>$ vim test.d<br />
import std.stdio;<br />
void main()<br />
{<br />
writeln(&quot;hello world from D!&quot;);<br />
writeln(&quot;3.14 * 2 = &quot;, 3.14*2);<br />
}</pre><br />
Then compile the test program like this:<br />
<br />
<pre>ldcarm test.d -of testd</pre><br />
<code>-of</code> tells ldc to output the compiled executable using <code>testd</code> filename rother than default <code>test</code>.<br />
<br />
Now, copy the testd to your arm target, type <code>./testd</code> and make a breath.<br />
<br />
<pre>$ ./testd<br />
hello world from D!<br />
3.14 * 2 = 6.28</pre><br />
Wow! we finally reach the point! Congratulations!<br />
<br />
== 6. the dub managed project ==<br />
<br />
For complex testing, we will use dub to init a vibe.d hello world project.<br />
<br />
<pre>$ dub init vibeex --type=vibe.d<br />
Package recipe format (sdl/json) [json]: <br />
Name [vibeex]: <br />
Description [A simple vibe.d server application.]: <br />
Author name [dbh]: <br />
License [proprietary]: <br />
Copyright string [Copyright © 2018, dbh]: <br />
Add dependency (leave empty to skip) []: <br />
Successfully created an empty project in '/media/Devel/Changhong/IOT/imx6u-devel/project/vibeex'.<br />
Package successfully created in vibeex</pre><br />
The dub tool initialized a vibe.d example project, but the vibe.d dependency version is outdated. we need to tweak it.<br />
<br />
<pre>$ vim vibeex/dub.json<br />
{<br />
&quot;name&quot;: &quot;vibeex&quot;,<br />
&quot;authors&quot;: [<br />
&quot;dbh&quot;<br />
],<br />
&quot;dependencies&quot;: {<br />
&quot;vibe-d&quot;: &quot;~&gt;0.7.30&quot;<br />
},<br />
&quot;description&quot;: &quot;A simple vibe.d server application.&quot;,<br />
&quot;copyright&quot;: &quot;Copyright © 2018, dbh&quot;,<br />
&quot;license&quot;: &quot;proprietary&quot;<br />
}</pre><br />
update 0.7.30 to 0.8.3.<br />
<br />
when building using dub, the alias method setup ldc-arm will not work. we need to turn this into a shell script adapter:<br />
<br />
<pre>#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ldc2 -mtriple=arm-linux-gnueabihf -gcc=arm-linux-gnueabihf-gcc -L=-L${LDC2ARMRUNTIME}/lib $@</pre><br />
''for yocto toolchain, you will have an adapter like bellow:''<br />
<br />
<pre>$ cat ldc-yocto-arm<br />
#!/bin/sh<br />
<br />
LDC2ARMRUNTIME=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/ldc2Armhf_runtime<br />
ARMTARGETROOT=/media/Devel/Changhong/IOT/imx6u-devel/toolchain/yocto/targetroot<br />
ldc2 -mtriple=arm-poky-linux-gnueabi -float-abi=hard -mcpu=cortex-a7 -gcc=arm-poky-linux-gnueabi-gcc -L=-L${LDC2ARMRUNTIME}/lib -Xcc=--sysroot=$ARMTARGETROOT $@</pre><br />
'''NOTE''': if your toolchain does not have some library for the arm target present, dub will fail like this:<br />
<br />
Then compile the project using commands below:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
vibeex ~master: building configuration &quot;application&quot;...</pre><br />
<br />
however, sometime we would have no luck, and got something like this:<br />
<br />
<pre>$ dub build --compiler=ldc-arm<br />
Performing &quot;debug&quot; build using ldc-arm for arm, arm_hardfloat.<br />
taggedalgebraic 0.10.9: building configuration &quot;library&quot;...<br />
eventcore 0.8.30: building configuration &quot;epoll&quot;...<br />
stdx-allocator 2.77.0: building configuration &quot;library&quot;...<br />
vibe-core 1.4.0: building configuration &quot;epoll&quot;...<br />
vibe-d:utils 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:data 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:crypto 0.8.3: building configuration &quot;library&quot;...<br />
diet-ng 1.4.5: building configuration &quot;library&quot;...<br />
vibe-d:stream 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:textfilter 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:inet 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:tls 0.8.3: building configuration &quot;openssl&quot;...<br />
vibe-d:http 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mail 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:mongodb 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:redis 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d:web 0.8.3: building configuration &quot;library&quot;...<br />
vibe-d 0.8.3: building configuration &quot;vibe-core&quot;...<br />
hellovibe ~master: building configuration &quot;application&quot;...<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto<br />
/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz<br />
collect2: error: ld returned 1 exit status<br />
Error: /usr/bin/arm-linux-gnueabihf-gcc failed with status: 1<br />
ldc-arm failed with exit code 1.<br />
</pre><br />
This means that all library path does not includes libssl, libcrypto, libz. You need to find or build a toolchain with extra lib built-in, or, just cross-compiling the desired c library and install to your toolchain sysroot path.<br />
<br />
Let’s run the vibe.d example on arm target:<br />
<br />
<pre>root@chiot:~# ls -lh<br />
total 25M<br />
-rwxr-xr-x 1 root root 24M Mar 12 05:53 vibeex<br />
<br />
root@chiot:~# ./vibeex <br />
[main(----) INF] Listening for requests on http://[::1]:8080/<br />
[main(----) INF] Listening for requests on http://127.0.0.1:8080/<br />
[main(----) INF] Please open http://127.0.0.1:8080/ in your browser.<br />
Vibe was run as root, and no user/group has been specified for privilege lowering. Running with full permissions.</pre><br />
<br />
<br />
Yeah! we finally did that!</div>
Dangbinghoo
https://wiki.dlang.org/?title=Tutorials&diff=9084
Tutorials
2018-03-14T09:03:21Z
<p>Dangbinghoo: /* How To */</p>
<hr />
<div>== Videos Tutorials ==<br />
* [[Videos#Tutorials | Video tutorials]]<br />
<br />
== Best Practices ==<br />
* [[Order of import statements]]<br />
* [[Portability and performance]]<br />
* [[Conventional module name for importing all modules in a package]]<br />
<br />
== Common Idioms ==<br />
<br />
Although D inherited much of its syntax from C and C++, the new features that it introduces lead to some common idioms that are unique to D.<br />
See also category [[:Category:CommonIdiom|CommonIdiom]].<br />
<br />
* [[Initializing variables]]<br />
* [[Declaring constants]]<br />
* [[Looping over integers]]<br />
* [[Unittest#Placement|Unittest placement]]<br />
** [[Unittest#Unittest-specific imports and helper functions|Imports and helper functions only present when compiling with -unittest]]<br />
* [[Commenting out code]]<br />
* [[Dense multidimensional arrays|Declaring dense multidimensional arrays]]<br />
* [[Voldemort types]]<br />
<br />
== Design Patterns ==<br />
<br />
* [[Instantiator Function Pattern]] - Instantiating classes and structs with minimal redundancy.<br />
* [[Compile-time Command Pattern]] - Store function and arguments to be invoked later.<br />
* [[Higher Order Range Pattern]] - Transform a range before passing it to a function/object.<br />
* [[Mixin Macros Pattern]] - Mixins + Compile-Time Magic<br />
* [[Low-Lock Singleton Pattern]] - Singletons without double-checked locking<br />
<br />
== How To ==<br />
See also category [[:Category:HowTo|HowTo]].<br />
* [[Bind D to C]]<br />
* [[Compiling_and_linking_with_DMD_on_Windows|Compile and link with DMD on Windows]]<br />
* [[Linking_With_Unilink|Link with the Unilink linker on Windows instead of Optlink]]<br />
* [[Convert header files with SED]]<br />
* [[Defining custom print format specifiers|Define custom print format specifiers]]<br />
* [[Function literals]]<br />
* [[Implicit conversions in user types|Implicitly convert a user-defined type to a builtin type]]<br />
* [[Output locale character (MBS) to console]]<br />
* [[Promote D Projects]]<br />
* [[Regular expressions]]<br />
* [[Runtime type information (RTTI)]]<br />
* [[Run D in a CGI (web) environment]]<br />
* [[Tame OPTLINK]]<br />
* [[Unittest|Run unit tests]]<br />
* [[Using NASM with D]]<br />
* [[Read table data from file|Split file into multidimensional dynamic string array]]<br />
* [[Porting 32 Bit Code to 64 Bits]]<br />
* [[Converting C .h Files to D Modules]]<br />
* [[Instantiating Class Objects Elsewhere Than the GC Heap]]<br />
* [[Timing Code]]<br />
* [[Extending Unit Tests]]<br />
* [[Running DMD From The Command Prompt]]<br />
* [[Perf]]<br />
* [[Floating Point Gotchas]]<br />
* [[LDC+Dub+Vibe.d on SmartOS 64bit]]<br />
* [[Call D from Ruby using FFI]]<br />
* [[Programming in D tutorial on Embedded Linux ARM devices]]<br />
<br />
=== Microsoft Windows ===<br />
* [[D for Win32]]<br />
* [[Win32 DLLs in D]]<br />
* [[COM Programming]]<br />
* [[Using UTF on Windows]]<br />
<br />
[[Category:Tutorials]].</div>
Dangbinghoo