Skip to contentSkip to conversation

erlang: use erlang's native atomic ops

PATCH Superseded Frank Hunleth 2 participants 5 messages Feb 21, 2016 – Mar 6, 2016

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH v3 1/2 erlang: use erlang's native atomic ops

Now that we're using Erlang 18, the preferred atomic ops implementation for Erlang is its own built-in implementation, so use it. It is still possible to use libatomic_ops if the native implementation does not work. BR2_PACKAGE_ERLANG_ARCH_SUPPORTS is added now that BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS is no longer appropriate for checking whether Erlang can be built for a platform.

This fixes an autobuilder failure when using libatomic_ops on aarch64. Erlang's native atomic ops implementation works on this platform.

Fixes:
http://autobuild.buildroot.net/results/0cd/0cd22eb74fa29e5a85bf897762e16ab3daf33962/

---
Changes v2->v3:
- Move LIBS=-latomic_ops change to a separate commit
- Rebased to pull in BR2_PACKAGE_LIBATOMIC_ARCH_SUPPORTS to BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS change
- Note that the BR2_PACKAGE_ERLANG_ARCH_SUPPORTS caused me to move the missing dependencies comment from the beginning of the file down to the end.
- Made libatomic_ops a selection for now per comment from Romain Naour. While Erlang supports a lot of options, libatomic_ops was the only alternative in the choices. Even then, it may not be used that often since the Erlang native support covers most platforms.

Changes v1->v2:
- Add BR2_PACKAGE_ERLANG_ARCH_SUPPORTS and related changes (Thanks to Thomas)
- Atomic ops selection is a choice now due to the potential for more than two options based on the Erlang documentation.
- Line wrapping updates
- Added note on Erlang choosing native atomic ops even if libatomic_ops is present.
- Removed LIBS=-latomic_ops. The ./configure test for it still worked, and Erlang linked to it without errors.

 package/erlang/Config.in | 41 +++++++++++++++++++++++++++++++++++------
 package/erlang/erlang.mk |  4 ++++
 2 files changed, 39 insertions(+), 6 deletions(-)
package/erlang/Config.in +35 -6
index 5fa2028..d17fb7a 100644
@@ -1,14 +1,30 @@
-comment "erlang needs a toolchain w/ dynamic library"
-	depends on BR2_USE_MMU # fork()
-	depends on BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS
-	depends on BR2_STATIC_LIBS
+# Erlang requires platform support for atomic operations. See the
+# HOWTO/INSTALL.md file for the full description. A summary of the
+# options is as follows:
+#
+#   1. Erlang's atomic operations on 32/64-bit x86, 32/64-bit
+#      SPARC V9, 32-bit PowerPC, or 32-bit Tile. The INSTALL.md
+#      omits 32/64-bit ARM support, but those are supported as well.
+#   2. The API provided by Windows (N/A for Buildroot)
+#   3. Native atomic operations provided by the '__atomic_*' builtins
+#      with gcc 4.7 or later.
+#   4. libatomic_ops
+#   5. The availability of __sync_*() operations. Based on
+#      http://autobuild.buildroot.org/results/209/2090874eee165af3349cf2d597657fc1b4ca1012/build-end.log,
+#      it needs the 4-byte and 8-byte versions.
+#
+# Cases 3 and 5 do not appear to work on configurations that are not
+# included in 1 and 4 due to compiler errors.
+config BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
+	bool
+	default y if BR2_i386 || BR2_x86_64 || BR2_powerpc || BR2_sparc_v9 || BR2_arm || BR2_aarch64 # case (1)
+	default y if BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS # case (4)
 
 config BR2_PACKAGE_ERLANG
 	bool "erlang"
 	depends on BR2_USE_MMU # fork()
 	depends on !BR2_STATIC_LIBS
-	depends on BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS
-	select BR2_PACKAGE_LIBATOMIC_OPS
+	depends on BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
 	help
 	  Erlang is a programming language used to build massively scalable
 	  soft real-time systems with requirements on high availability.
@@ -20,6 +36,14 @@ config BR2_PACKAGE_ERLANG
 
 if BR2_PACKAGE_ERLANG
 
+config BR2_PACKAGE_ERLANG_LIBATOMIC_OPS
+	bool "libatomic_ops"
+	depends on BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS
+	depends on !BR2_aarch64 # causes build failures
+	select BR2_PACKAGE_LIBATOMIC_OPS
+	help
+	  Use libatomic_ops instead of Erlang's native atomic ops support.
+
 config BR2_PACKAGE_ERLANG_SMP
 	bool "enable SMP support"
 	help
@@ -38,3 +62,8 @@ config BR2_PACKAGE_ERLANG_MEGACO
 	  enable it.
 
 endif # BR2_PACKAGE_ERLANG
+
+comment "erlang needs a toolchain w/ dynamic library, atomic_ops"
+	depends on BR2_USE_MMU # fork()
+	depends on BR2_STATIC_LIBS || !BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
+
package/erlang/erlang.mk +4 -0
index 638d2c2..8257ab4 100644
@@ -30,8 +30,12 @@ ERLANG_CONF_ENV += erl_xcomp_sysroot=$(STAGING_DIR)
 
 ERLANG_CONF_OPTS = --without-javac
 
+# Erlang uses its own native atomic ops implementation if support is
+# available. Override this if the user wants libatomic_ops.
+ifeq ($(BR2_PACKAGE_ERLANG_LIBATOMIC_OPS),y)
 ERLANG_DEPENDENCIES += libatomic_ops
 ERLANG_CONF_OPTS += --with-libatomic_ops=$(STAGING_DIR)/usr LIBS=-latomic_ops
+endif
 
 # erlang uses openssl for all things crypto. Since the host tools (such as
 # rebar) uses crypto, we need to build host-erlang with support for openssl.
Signature · 1 line
2.5.0
#1 lore raw

PATCH v3 2/2 erlang: remove extraneous LIBS=-latomic_ops

As suggested by Thomas Petazzoni, this isn't needed when building with libatomic_ops.

---
Changes v2->v3:
- Pulled LIBS=-libatomic_ops removal into a separate patch

 package/erlang/erlang.mk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
package/erlang/erlang.mk +1 -1
index 8257ab4..b1c8e35 100644
@@ -34,7 +34,7 @@ ERLANG_CONF_OPTS = --without-javac
 # available. Override this if the user wants libatomic_ops.
 ifeq ($(BR2_PACKAGE_ERLANG_LIBATOMIC_OPS),y)
 ERLANG_DEPENDENCIES += libatomic_ops
-ERLANG_CONF_OPTS += --with-libatomic_ops=$(STAGING_DIR)/usr LIBS=-latomic_ops
+ERLANG_CONF_OPTS += --with-libatomic_ops=$(STAGING_DIR)/usr
 endif
 
 # erlang uses openssl for all things crypto. Since the host tools (such as
Signature · 1 line
2.5.0
#2 lore raw

PATCH v3 1/2 erlang: use erlang's native atomic ops

In reply to Frank Hunleth
Quoted 15 lines · Frank Hunleth

Now that we're using Erlang 18, the preferred atomic ops implementation for Erlang is its own built-in implementation, so use it. It is still possible to use libatomic_ops if the native implementation does not work. BR2_PACKAGE_ERLANG_ARCH_SUPPORTS is added now that BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS is no longer appropriate for checking whether Erlang can be built for a platform.

This fixes an autobuilder failure when using libatomic_ops on aarch64. Erlang's native atomic ops implementation works on this platform.

Fixes:
http://autobuild.buildroot.net/results/0cd/0cd22eb74fa29e5a85bf897762e16ab3daf33962/

---

[snip]

package/erlang/Config.in line 20

Quoted 3 lines
package/erlang/Config.in +3 -0
+config BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
+	bool
+	default y if BR2_i386 || BR2_x86_64 || BR2_powerpc || BR2_sparc_v9 || BR2_arm || BR2_aarch64 # case (1)

This line is too long, please split it.

Quoted 13 lines
package/erlang/Config.in +2 -2
+	default y if BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS # case (4)
 
 config BR2_PACKAGE_ERLANG
 	bool "erlang"
 	depends on BR2_USE_MMU # fork()
 	depends on !BR2_STATIC_LIBS
-	depends on BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS
-	select BR2_PACKAGE_LIBATOMIC_OPS
+	depends on BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
 	help
 	  Erlang is a programming language used to build massively scalable
 	  soft real-time systems with requirements on high availability.

package/erlang/Config.in config BR2_PACKAGE_ERLANG · line 40

Quoted 5 lines
package/erlang/Config.in +2 -0
@@ -20,6 +36,14 @@ config BR2_PACKAGE_ERLANG
 
 if BR2_PACKAGE_ERLANG
 
+config BR2_PACKAGE_ERLANG_LIBATOMIC_OPS
+	bool "libatomic_ops"

Does it make sense to let the user select this? I don't think so...

I think we should have:

config BR2_PACKAGE_ERLANG_ARCH_SUPPORTS_DIRECTLY # case (1)

	bool
	default y if BR2_i386 || BR2_x86_64 || BR2_powerpc || \
		BR2_sparc_v9 || BR2_arm # aarch64 causes build failures

config BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
bool
default y if BR2_PACKAGE_ERLANG_ARCH_SUPPORTS_DIRECTLY default y if BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS # case (4)

and nothing more.

Quoted 10 lines
package/erlang/Config.in +6 -0
+	depends on BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS
+	depends on !BR2_aarch64 # causes build failures
+	select BR2_PACKAGE_LIBATOMIC_OPS
+	help
+	  Use libatomic_ops instead of Erlang's native atomic ops support.
+
 config BR2_PACKAGE_ERLANG_SMP
 	bool "enable SMP support"
 	help

package/erlang/Config.in config BR2_PACKAGE_ERLANG_MEGACO · line 68

Quoted 7 lines
package/erlang/Config.in +4 -0
@@ -38,3 +62,8 @@ config BR2_PACKAGE_ERLANG_MEGACO
 	  enable it.
 
 endif # BR2_PACKAGE_ERLANG
+
+comment "erlang needs a toolchain w/ dynamic library, atomic_ops"
+	depends on BR2_USE_MMU # fork()
+	depends on BR2_STATIC_LIBS || !BR2_PACKAGE_ERLANG_ARCH_SUPPORTS

This should depend on BR2_PACKAGE_ERLANG_ARCH_SUPPORTS, so:

comment "erlang needs a toolchain w/ dynamic library"
depends on BR2_PACKAGE_ERLANG_ARCH_SUPPORTS depends on BR2_USE_MMU # fork() depends on BR2_STATIC_LIBS

and that should ideally be a separate patch, or at least mentioned in the commit message.

package/erlang/erlang.mk ERLANG_CONF_ENV += erl_xcomp_sysroot=$(STAGING_DIR) · line 35

Quoted 12 lines
(quoted diff) +1 -0
+
package/erlang/erlang.mk +3 -0
index 638d2c2..8257ab4 100644
@@ -30,8 +30,12 @@ ERLANG_CONF_ENV += erl_xcomp_sysroot=$(STAGING_DIR)
 
 ERLANG_CONF_OPTS = --without-javac
 
+# Erlang uses its own native atomic ops implementation if support is
+# available. Override this if the user wants libatomic_ops.
+ifeq ($(BR2_PACKAGE_ERLANG_LIBATOMIC_OPS),y)

So here it should be

ifeq ($(BR2_PACKAGE_ERLANG_ARCH_SUPPORTS_DIRECTLY),)

Regards,
Arnout

Quoted 7 lines
package/erlang/erlang.mk +1 -0
 ERLANG_DEPENDENCIES += libatomic_ops
 ERLANG_CONF_OPTS += --with-libatomic_ops=$(STAGING_DIR)/usr LIBS=-latomic_ops
+endif
 
 # erlang uses openssl for all things crypto. Since the host tools (such as
 # rebar) uses crypto, we need to build host-erlang with support for openssl.
Signature · 6 lines
Arnout Vandecappelle                          arnout at mind be
Senior Embedded Software Architect            +32-16-286500
Essensium/Mind                                http://www.mind.be
G.Geenslaan 9, 3001 Leuven, Belgium           BE 872 984 063 RPR Leuven
LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
GPG fingerprint:  7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF
#3 lore raw

PATCH v3 1/2 erlang: use erlang's native atomic ops

Hi Arnout, all,

Quoted 51 lines · Arnout Vandecappelle
Quoted 15 lines · Frank Hunleth

Now that we're using Erlang 18, the preferred atomic ops implementation for Erlang is its own built-in implementation, so use it. It is still possible to use libatomic_ops if the native implementation does not work. BR2_PACKAGE_ERLANG_ARCH_SUPPORTS is added now that BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS is no longer appropriate for checking whether Erlang can be built for a platform.

This fixes an autobuilder failure when using libatomic_ops on aarch64. Erlang's native atomic ops implementation works on this platform.

Fixes:
http://autobuild.buildroot.net/results/0cd/0cd22eb74fa29e5a85bf897762e16ab3daf33962/

---

[snip]

package/erlang/Config.in line 20

Quoted 3 lines
package/erlang/Config.in +3 -0
+config BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
+     bool
+     default y if BR2_i386 || BR2_x86_64 || BR2_powerpc || BR2_sparc_v9 || BR2_arm || BR2_aarch64 # case (1)

This line is too long, please split it.

Quoted 13 lines
package/erlang/Config.in +2 -2
+     default y if BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS # case (4)
 
 config BR2_PACKAGE_ERLANG
      bool "erlang"
      depends on BR2_USE_MMU # fork()
      depends on !BR2_STATIC_LIBS
-     depends on BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS
-     select BR2_PACKAGE_LIBATOMIC_OPS
+     depends on BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
      help
        Erlang is a programming language used to build massively scalable
        soft real-time systems with requirements on high availability.

package/erlang/Config.in config BR2_PACKAGE_ERLANG · line 40

Quoted 5 lines
package/erlang/Config.in +2 -0
@@ -20,6 +36,14 @@ config BR2_PACKAGE_ERLANG
 
 if BR2_PACKAGE_ERLANG
 
+config BR2_PACKAGE_ERLANG_LIBATOMIC_OPS
+     bool "libatomic_ops"

Does it make sense to let the user select this? I don't think so...

I think we should have:

config BR2_PACKAGE_ERLANG_ARCH_SUPPORTS_DIRECTLY # case (1)

        bool
        default y if BR2_i386 || BR2_x86_64 || BR2_powerpc || \
                BR2_sparc_v9 || BR2_arm # aarch64 causes build failures
Quoted 6 lines

config BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
bool
default y if BR2_PACKAGE_ERLANG_ARCH_SUPPORTS_DIRECTLY default y if BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS # case (4)

and nothing more.

The more I think about this patch, the more I want to drop all references to libatomic_ops. The reason is that the native Erlang atomic ops implementation supports almost every platform supported by libatomic_ops. In fact, it looks like every _defconfig in Buildroot that supports Erlang uses the native atomic ops implementation rather than libatomic_ops. (I actually tried building all _defconfigs at one point, but I'll double check if there are doubts.)

Does it make sense to remove libatomic_ops altogether? I think the original reason for including it doesn't apply now that we upgraded to Erlang 18.

Thanks,
Frank

Quoted 66 lines
Quoted 11 lines
package/erlang/Config.in +6 -0
+     depends on BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS
+     depends on !BR2_aarch64 # causes build failures
+     select BR2_PACKAGE_LIBATOMIC_OPS
+     help
+       Use libatomic_ops instead of Erlang's native atomic ops support.
+
 config BR2_PACKAGE_ERLANG_SMP
      bool "enable SMP support"
      help

package/erlang/Config.in config BR2_PACKAGE_ERLANG_MEGACO · line 68

Quoted 7 lines
package/erlang/Config.in +4 -0
@@ -38,3 +62,8 @@ config BR2_PACKAGE_ERLANG_MEGACO
        enable it.
 
 endif # BR2_PACKAGE_ERLANG
+
+comment "erlang needs a toolchain w/ dynamic library, atomic_ops"
+     depends on BR2_USE_MMU # fork()
+     depends on BR2_STATIC_LIBS || !BR2_PACKAGE_ERLANG_ARCH_SUPPORTS

This should depend on BR2_PACKAGE_ERLANG_ARCH_SUPPORTS, so:

comment "erlang needs a toolchain w/ dynamic library"
depends on BR2_PACKAGE_ERLANG_ARCH_SUPPORTS depends on BR2_USE_MMU # fork() depends on BR2_STATIC_LIBS

and that should ideally be a separate patch, or at least mentioned in the commit message.

package/erlang/erlang.mk ERLANG_CONF_ENV += erl_xcomp_sysroot=$(STAGING_DIR) · line 35

Quoted 12 lines
(quoted diff) +1 -0
+
package/erlang/erlang.mk +3 -0
index 638d2c2..8257ab4 100644
@@ -30,8 +30,12 @@ ERLANG_CONF_ENV += erl_xcomp_sysroot=$(STAGING_DIR)
 
 ERLANG_CONF_OPTS = --without-javac
 
+# Erlang uses its own native atomic ops implementation if support is
+# available. Override this if the user wants libatomic_ops.
+ifeq ($(BR2_PACKAGE_ERLANG_LIBATOMIC_OPS),y)

So here it should be

ifeq ($(BR2_PACKAGE_ERLANG_ARCH_SUPPORTS_DIRECTLY),)

Regards,
Arnout

package/erlang/erlang.mk ERLANG_CONF_ENV += erl_xcomp_sysroot=$(STAGING_DIR) · line 41

Quoted 7 lines
package/erlang/erlang.mk +1 -0
 ERLANG_DEPENDENCIES += libatomic_ops
 ERLANG_CONF_OPTS += --with-libatomic_ops=$(STAGING_DIR)/usr LIBS=-latomic_ops
+endif
 
 # erlang uses openssl for all things crypto. Since the host tools (such as
 # rebar) uses crypto, we need to build host-erlang with support for openssl.

--

Arnout Vandecappelle                          arnout at mind be
Senior Embedded Software Architect            +32-16-286500
Essensium/Mind                                http://www.mind.be
G.Geenslaan 9, 3001 Leuven, Belgium           BE 872 984 063 RPR Leuven
LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
GPG fingerprint:  7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF
Signature · 4 lines
Frank Hunleth
Troodon Software LLC
Embedded Software Development
http://troodon-software.com/
#4 lore raw

PATCH v3 1/2 erlang: use erlang's native atomic ops

Quoted 69 lines · Frank Hunleth

Hi Arnout, all,

Quoted 51 lines · Arnout Vandecappelle
Quoted 15 lines · Frank Hunleth

Now that we're using Erlang 18, the preferred atomic ops implementation for Erlang is its own built-in implementation, so use it. It is still possible to use libatomic_ops if the native implementation does not work. BR2_PACKAGE_ERLANG_ARCH_SUPPORTS is added now that BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS is no longer appropriate for checking whether Erlang can be built for a platform.

This fixes an autobuilder failure when using libatomic_ops on aarch64. Erlang's native atomic ops implementation works on this platform.

Fixes:
http://autobuild.buildroot.net/results/0cd/0cd22eb74fa29e5a85bf897762e16ab3daf33962/

---

[snip]

package/erlang/Config.in line 20

Quoted 3 lines
package/erlang/Config.in +3 -0
+config BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
+     bool
+     default y if BR2_i386 || BR2_x86_64 || BR2_powerpc || BR2_sparc_v9 || BR2_arm || BR2_aarch64 # case (1)

This line is too long, please split it.

Quoted 13 lines
package/erlang/Config.in +2 -2
+     default y if BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS # case (4)
 
 config BR2_PACKAGE_ERLANG
      bool "erlang"
      depends on BR2_USE_MMU # fork()
      depends on !BR2_STATIC_LIBS
-     depends on BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS
-     select BR2_PACKAGE_LIBATOMIC_OPS
+     depends on BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
      help
        Erlang is a programming language used to build massively scalable
        soft real-time systems with requirements on high availability.

package/erlang/Config.in config BR2_PACKAGE_ERLANG · line 40

Quoted 5 lines
package/erlang/Config.in +2 -0
@@ -20,6 +36,14 @@ config BR2_PACKAGE_ERLANG
 
 if BR2_PACKAGE_ERLANG
 
+config BR2_PACKAGE_ERLANG_LIBATOMIC_OPS
+     bool "libatomic_ops"

Does it make sense to let the user select this? I don't think so...

I think we should have:

config BR2_PACKAGE_ERLANG_ARCH_SUPPORTS_DIRECTLY # case (1)

        bool
        default y if BR2_i386 || BR2_x86_64 || BR2_powerpc || \
                BR2_sparc_v9 || BR2_arm # aarch64 causes build failures
Quoted 6 lines

config BR2_PACKAGE_ERLANG_ARCH_SUPPORTS
bool
default y if BR2_PACKAGE_ERLANG_ARCH_SUPPORTS_DIRECTLY default y if BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS # case (4)

and nothing more.

The more I think about this patch, the more I want to drop all references to libatomic_ops. The reason is that the native Erlang atomic ops implementation supports almost every platform supported by libatomic_ops. In fact, it looks like every _defconfig in Buildroot that supports Erlang uses the native atomic ops implementation rather than libatomic_ops. (I actually tried building all _defconfigs at one point, but I'll double check if there are doubts.)

Quoted 3 lines

Does it make sense to remove libatomic_ops altogether? I think the original reason for including it doesn't apply now that we upgraded to Erlang 18.

Sounds OK to me.

Regards,
Arnout

Quoted 12 lines

Thanks,
Frank

Quoted 7 lines
Quoted 7 lines
package/erlang/Config.in +6 -0
+     depends on BR2_PACKAGE_LIBATOMIC_OPS_ARCH_SUPPORTS
+     depends on !BR2_aarch64 # causes build failures
+     select BR2_PACKAGE_LIBATOMIC_OPS
+     help
+       Use libatomic_ops instead of Erlang's native atomic ops support.
+

[snip]

Signature · 6 lines
Arnout Vandecappelle                          arnout at mind be
Senior Embedded Software Architect            +32-16-286500
Essensium/Mind                                http://www.mind.be
G.Geenslaan 9, 3001 Leuven, Belgium           BE 872 984 063 RPR Leuven
LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
GPG fingerprint:  7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF