How to compile native extension with C++11 features? (DEF-2594) (SOLVED)

I am making a native extension for advanced sound processing (3D sound, sound effects, etc). I’ve picked YSE sound engine to use, it has binaries for most platforms.
Since extensions are compiled in the cloud, I have no control over how are they built. In this case YSE needs C++11 features to be turned on. In particular it uses atomic types.

The output:

Description	Resource	Path	Location	Type
clang++ -c -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -DDM_PLATFORM_OSX   -I/tmp/upload4378530617527777636/yse/include  -F/tmp/upload4378530617527777636/yse/lib/x86_64-osx  -I/var/extender/sdk/0d7f8b51658bee90cb38f3d651b3ba072394afed/defoldsdk/include -I/var/extender/sdk/0d7f8b51658bee90cb38f3d651b3ba072394afed/defoldsdk/sdk/include  /tmp/upload4378530617527777636/yse/src/yse.cpp -o/var/extender/builds/build3923986835358081452/yse.cpp_0.o
In file included from /tmp/upload4378530617527777636/yse/src/yse.cpp:15:
/tmp/upload4378530617527777636/yse/include/yse.hpp:16:10: fatal error: 'atomic' file not found
#include <atomic>
         ^
1 error generated.

	yse.hpp	/extension-yse/content/yse/include	line 1	Problem

To turn on C++11 clang should be run with the -std=c++11 option. Can it be turned on?

While I am developing on macOS, I believe other platforms might suffer the same problem, but I couldn’t try yet. How do I specify in the ext.manifest file that the extension targets all platforms? Defold says the platform I am trying to bundle for is not supported in ext.manifest.

3 Likes

Hi @sergey.lerg!

Although the extensions are currently built in the cloud, you can set some flags and options. See the documentation for some examples.

To enable C++11, you should set it in the flags like so:

name: MyExtension

platforms:
    x86-osx:
        context:
            flags:  ["-std=c++11"]

    x86_64-osx:
        context:
            flags:  ["-std=c++11"]

Bear in mind that this feature is still in an alpha stage, and does not yet support all platforms or features (OSX, iOS, Android (C++ only)). What platform did you try to bundle for?

3 Likes

Somehow I missed that documentation page. Thanks for it.
Yeah, I thought Win and Linux support for extensions is in place, but now I see.
Also, I’ve found out that YSE has GPL part, so that’s a no go.
That leaves me with OpenAL or a wrapper for it.

2 Likes

Hello again.
So I was able to compile a primitive example of producing just some sound with OpenAL extension.
Then I added more code, added unordered_map usage from C++11 and after that I can’t compile anymore, not sure if it’s libc++ usage issue, the error message is pretty vague - complaining about undefined symbols for some trees in libddf.a during linking.

Here is the error output:

Description	Resource	Path	Location	Type
clang++ -c -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -DDM_PLATFORM_OSX  -std=c++11 -stdlib=libc++  -I/tmp/upload8943013805498600597/openal/include  -F/tmp/upload8943013805498600597/openal/lib/x86_64-osx  -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/include -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/sdk/include  /tmp/upload8943013805498600597/openal/src/common/alhelpers.c -o/var/extender/builds/build5475874394508082934/alhelpers.c_0.o
clang-3.9: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated

clang++ -c -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -DDM_PLATFORM_OSX  -std=c++11 -stdlib=libc++  -I/tmp/upload8943013805498600597/openal/include  -F/tmp/upload8943013805498600597/openal/lib/x86_64-osx  -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/include -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/sdk/include  /tmp/upload8943013805498600597/openal/src/extension.cpp -o/var/extender/builds/build5475874394508082934/extension.cpp_1.o

clang++ -c -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -DDM_PLATFORM_OSX  -std=c++11 -stdlib=libc++  -I/tmp/upload8943013805498600597/openal/include  -F/tmp/upload8943013805498600597/openal/lib/x86_64-osx  -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/include -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/sdk/include  /tmp/upload8943013805498600597/openal/src/openal.cpp -o/var/extender/builds/build5475874394508082934/openal.cpp_2.o

llvm-ar rcs /var/extender/builds/build5475874394508082934/libaf924bd0-d573-4e7d-aba6-5ab645af518b.a /var/extender/builds/build5475874394508082934/alhelpers.c_0.o /var/extender/builds/build5475874394508082934/extension.cpp_1.o /var/extender/builds/build5475874394508082934/openal.cpp_2.o 

clang++ -c -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -DDM_PLATFORM_OSX  -std=c++11 -stdlib=libc++    -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/include -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/sdk/include  /var/extender/builds/build5475874394508082934/main.cpp -o/var/extender/builds/build5475874394508082934/main_tmpd3869afa-21f5-4c24-aed8-0a53a03a1aa7.o

clang++ -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -o /var/extender/builds/build5475874394508082934/dmengine -stdlib=libc++  -L/var/extender/builds/build5475874394508082934 -L/tmp/upload8943013805498600597/openal/lib/x86_64-osx  -lc++  -laf924bd0-d573-4e7d-aba6-5ab645af518b -lopenal  -F/var/extender/builds/build5475874394508082934 -F/tmp/upload8943013805498600597/openal/lib/x86_64-osx -F/tmp/upload8943013805498600597/openal/lib/x86_64-osx   -framework Foundation -framework AppKit -framework Cocoa -framework OpenGL -framework OpenAL -framework AGL -framework IOKit -framework Carbon -framework CoreVideo  -L/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/lib/x86_64-darwin -L/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/ext/lib/x86_64-darwin  -lengine -ladtruthext -lfacebookext -liapext -lpushext -liacext -lrecord -lgameobject -lddf -lresource -lgamesys -lgraphics -lphysics -lBulletDynamics -lBulletCollision -lLinearMath -lBox2D -lrender -lscript -llua -lextension -lhid -linput -lparticle -lrig -ldlib -ldmglfw -lgui -ltracking -lcrashext -lsound -ltremolo -lvpx -lliveupdate  /var/extender/builds/build5475874394508082934/main_tmpd3869afa-21f5-4c24-aed8-0a53a03a1aa7.o 
Undefined symbols for architecture x86_64:
  "__ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base", referenced from:
      __ZNSt8_Rb_treeIySt4pairIKyjESt10_Select1stIS2_ESt4lessIyESaIS2_EE16_M_insert_uniqueESt17_Rb_tree_iteratorIS2_ERKS2_ in libddf.a(ddf_loadcontext_5.o)
      __ZNSt8_Rb_treeIySt4pairIKyjESt10_Select1stIS2_ESt4lessIyESaIS2_EE16_M_insert_uniqueERKS2_ in libddf.a(ddf_loadcontext_5.o)
  "__ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base", referenced from:
      __ZNSt8_Rb_treeIySt4pairIKyjESt10_Select1stIS2_ESt4lessIyESaIS2_EE16_M_insert_uniqueESt17_Rb_tree_iteratorIS2_ERKS2_ in libddf.a(ddf_loadcontext_5.o)
  "__ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_", referenced from:
      __ZNSt8_Rb_treeIySt4pairIKyjESt10_Select1stIS2_ESt4lessIyESaIS2_EE16_M_insert_uniqueESt17_Rb_tree_iteratorIS2_ERKS2_ in libddf.a(ddf_loadcontext_5.o)
      __ZNSt8_Rb_treeIySt4pairIKyjESt10_Select1stIS2_ESt4lessIyESaIS2_EE16_M_insert_uniqueERKS2_ in libddf.a(ddf_loadcontext_5.o)
ld: symbol(s) not found for architecture x86_64
clang-3.9: error: linker command failed with exit code 1 (use -v to see invocation)

	ext.manifest	/extension-openal/content/openal	line 1	Problem

And here is my ext.manifest

name: "openal"

platforms:
    x86_64-osx:
        context:
            flags: ["-std=c++11", "-stdlib=libc++"]
            frameworks: []
            linkFlags: ["-stdlib=libc++"]
            libs: ["c++"]

Can you spot what’s wrong?

If I don’t use libc++, it builds fine.
I was stumbled by dmScript::LuaHBuffer and dmBuffer::HBuffer not being the same thing for a while, but implicit type conversion for dmBuffer::getBytes() did the trick.
It would be very useful to have all the header files available for download, documentation is not enough.

Anyway, after a sleepless night, here is a result. A quick and dirty proof of concept.

9 Likes

This does impress, I must say.
Soooo how shareable your code it? I bet fellow Defold users would want to play around with this?

5 Likes

I agree! Very very cool!

3 Likes

Hi @sergey.lerg

Well, I couldn’t really spot an error.
In my own example, I didn’t need to put “libc++” in the linkFlags setting, but in the flags setting.

Also, as you mentioned, the HLuaBuffer was added this release, but seems to have fallen out of the documentation.
Here is what it is looks like (so you don’t have to cast it!):

    /*# Lua wrapper for a buffer
     * 
     * Holds info about the buffer and who owns it
     */
    struct LuaHBuffer
    {
        dmBuffer::HBuffer   m_Buffer;
        bool                m_UseLuaGC;     //!< If true, Lua will delete the buffer in the Lua GC phase
    };

And also, cool demo!

3 Likes

I will release it on github when I make the extension a bit more usable. At the moment it doesn’t provide much control over the sound sources.

It doesn’t work this way for me either. I’ll provide more details on the build errors soon.

And thanks for the LuaHBuffer definition! Now I see why casting surprisingly worked, pure luck.

6 Likes

@Mathias_Westerdahl, so to recap the libc++ issue.
I want to use for instance unordered_map. I write #include <unordered_map> and get this error:

Description	Resource	Path	Location	Type
clang++ -c -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -DDM_PLATFORM_OSX   -I/tmp/upload8882111693246949285/openal/include  -F/tmp/upload8882111693246949285/openal/lib/x86_64-osx  -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/include -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/sdk/include  /tmp/upload8882111693246949285/openal/src/extension.cpp -o/var/extender/builds/build8151566694450167681/extension.cpp_0.o
In file included from /tmp/upload8882111693246949285/openal/src/extension.cpp:12:
/tmp/upload8882111693246949285/openal/src/openal.h:7:10: fatal error: 'unordered_map' file not found
#include <unordered_map>
         ^
1 error generated.

	openal.h	/extension-openal/content/openal/src	line 1	Problem
fatal error: 'unordered_map' file not found	openal.h	/extension-openal/content/openal/src	line 7	Problem

Fair enough, now I need to specify that I want libc++ during the compilation. I add it to the flags section.

name: "openal"

platforms:
    x86_64-osx:
        context:
            flags: ["-std=c++11", "-stdlib=libc++"]
            frameworks: []
            linkFlags: []
            libs: []

And get the same error:

Description	Resource	Path	Location	Type
clang++ -c -arch i386 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m32 -O2 -g -mmacosx-version-min=10.7 -DDM_PLATFORM_OSX -DLUA_BYTECODE_ENABLE   -I/tmp/upload3097681066102365404/openal/include   -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/include -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/sdk/include  /tmp/upload3097681066102365404/openal/src/extension.cpp -o/var/extender/builds/build4031484822964348167/extension.cpp_0.o
In file included from /tmp/upload3097681066102365404/openal/src/extension.cpp:12:
/tmp/upload3097681066102365404/openal/src/openal.h:7:10: fatal error: 'unordered_map' file not found
#include <unordered_map>
         ^
1 error generated.

	openal.h	/extension-openal/content/openal/src	line 1	Problem
fatal error: 'unordered_map' file not found	openal.h	/extension-openal/content/openal/src	line 7	Problem

For some reason I don’t see the specified flags in the command output.
But if I add to linkFlags.

name: "openal"

platforms:
    x86_64-osx:
        context:
            flags: ["-std=c++11", "-stdlib=libc++"]
            frameworks: []
            linkFlags: ["-stdlib=libc++"]
            libs: []

The error message changes

Description	Resource	Path	Location	Type
clang++ -c -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -DDM_PLATFORM_OSX  -std=c++11 -stdlib=libc++  -I/tmp/upload691423238232034599/openal/include  -F/tmp/upload691423238232034599/openal/lib/x86_64-osx  -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/include -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/sdk/include  /tmp/upload691423238232034599/openal/src/extension.cpp -o/var/extender/builds/build3582109968007015917/extension.cpp_0.o

clang++ -c -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -DDM_PLATFORM_OSX  -std=c++11 -stdlib=libc++  -I/tmp/upload691423238232034599/openal/include  -F/tmp/upload691423238232034599/openal/lib/x86_64-osx  -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/include -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/sdk/include  /tmp/upload691423238232034599/openal/src/openal.cpp -o/var/extender/builds/build3582109968007015917/openal.cpp_1.o

llvm-ar rcs /var/extender/builds/build3582109968007015917/lib27f64f14-e0c6-439f-8a45-f3cc3eec2a6b.a /var/extender/builds/build3582109968007015917/extension.cpp_0.o /var/extender/builds/build3582109968007015917/openal.cpp_1.o 

clang++ -c -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -DDM_PLATFORM_OSX  -std=c++11 -stdlib=libc++    -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/include -I/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/sdk/include  /var/extender/builds/build3582109968007015917/main.cpp -o/var/extender/builds/build3582109968007015917/main_tmpc1e02db3-f348-47f4-b805-ab40b742aa18.o

clang++ -arch x86_64 -target x86_64-apple-darwin11 -isysroot /opt/MacOSX.sdk/ -m64 -O2 -g -mmacosx-version-min=10.7 -o /var/extender/builds/build3582109968007015917/dmengine -stdlib=libc++  -L/var/extender/builds/build3582109968007015917 -L/tmp/upload691423238232034599/openal/lib/x86_64-osx   -l27f64f14-e0c6-439f-8a45-f3cc3eec2a6b  -F/var/extender/builds/build3582109968007015917 -F/tmp/upload691423238232034599/openal/lib/x86_64-osx -F/tmp/upload691423238232034599/openal/lib/x86_64-osx   -framework Foundation -framework AppKit -framework Cocoa -framework OpenGL -framework OpenAL -framework AGL -framework IOKit -framework Carbon -framework CoreVideo  -L/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/lib/x86_64-darwin -L/var/extender/sdk/1afccdb2cd42ca3bc7612a0496dfa6d434a8ebf9/defoldsdk/ext/lib/x86_64-darwin  -lengine -ladtruthext -lfacebookext -liapext -lpushext -liacext -lrecord -lgameobject -lddf -lresource -lgamesys -lgraphics -lphysics -lBulletDynamics -lBulletCollision -lLinearMath -lBox2D -lrender -lscript -llua -lextension -lhid -linput -lparticle -lrig -ldlib -ldmglfw -lgui -ltracking -lcrashext -lsound -ltremolo -lvpx -lliveupdate  /var/extender/builds/build3582109968007015917/main_tmpc1e02db3-f348-47f4-b805-ab40b742aa18.o 
Undefined symbols for architecture x86_64:
  "__ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base", referenced from:
      __ZNSt8_Rb_treeIySt4pairIKyjESt10_Select1stIS2_ESt4lessIyESaIS2_EE16_M_insert_uniqueESt17_Rb_tree_iteratorIS2_ERKS2_ in libddf.a(ddf_loadcontext_5.o)
      __ZNSt8_Rb_treeIySt4pairIKyjESt10_Select1stIS2_ESt4lessIyESaIS2_EE16_M_insert_uniqueERKS2_ in libddf.a(ddf_loadcontext_5.o)
  "__ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base", referenced from:
      __ZNSt8_Rb_treeIySt4pairIKyjESt10_Select1stIS2_ESt4lessIyESaIS2_EE16_M_insert_uniqueESt17_Rb_tree_iteratorIS2_ERKS2_ in libddf.a(ddf_loadcontext_5.o)
  "__ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_", referenced from:
      __ZNSt8_Rb_treeIySt4pairIKyjESt10_Select1stIS2_ESt4lessIyESaIS2_EE16_M_insert_uniqueESt17_Rb_tree_iteratorIS2_ERKS2_ in libddf.a(ddf_loadcontext_5.o)
      __ZNSt8_Rb_treeIySt4pairIKyjESt10_Select1stIS2_ESt4lessIyESaIS2_EE16_M_insert_uniqueERKS2_ in libddf.a(ddf_loadcontext_5.o)
ld: symbol(s) not found for architecture x86_64
clang-3.9: error: linker command failed with exit code 1 (use -v to see invocation)

	ext.manifest	/extension-openal/content/openal	line 1	Problem

This time the compiler flags are present, but linking fails due to some incompatibility with libddf? What is it, anyway?

I know these C++ features are not super crucial, but they make coding easier.

For some reason I don’t see the specified flags in the command output.

The thing here is that we build both 32/64 bit executables, so if you add the corresponding part for x86-osx, it should have given you the same result.

As for the final linker error, it seems we actually had a rogue “#include <map>” in our code, and they’ll clash. I’ve added ticket DEF-2594 for this.

In the meantime, as a workaround, you could perhaps use std::map without C++1) (It’s not a huge loss in performance, since they’re both pretty slow)

2 Likes

Yeah, I used std::map. C++11 can be useful later on.

Currently, I’ve exposed the most of OpenAL features in the extension. Pitch control, doppler effect, sound direction, etc.
Now I need to make a better example of how it all works and write a simple documentation.

After that I’ll try exposing effects (reverb) and filters. I haven’t tried yet, but I hope they are present in the binary.

1 Like

Released the first version of the extension. Details are here

3 Likes

I want to try adding flags for the compiler on Android, but I am getting “Internal Server Error”, even with empty flags list.

name: "openal"

platforms:
    armv7-android:
        context:
            flags: []
            frameworks: []
            linkFlags: []
            libs: []
Description	Resource	Path	Location	Type
Internal Server Error	ext.manifest	/extension-openal/content/openal	line 1	Problem

I guess that’s not normal?

@Mathias_Westerdahl, can you please confirm that the above behaviour is not normal? And if I could use compile flags on Android any time soon. Thanks!

HI @sergey.lerg!

It certainly doesn’t sound normal, I’ve used the flags without problems before, there’s no special treatment that way between platforms. I suspect the “Internal Server Error” comes from something else (not sure what yet).

I’m not entirely sure, but I think @mikael.lothman mentioned something the other day about the manifest not being able to handle mixed white spaces? Could that be something?
On a related note, the empty setup you show in your last post is the default setup, so you can omit it.

When you receive that error, the error is set on the first line of the ext.manifest, right? What can you see if you hover on that error with that file open? I suspect it could also be another linker error?

1 Like

Huh. Looks like something indeed was wrong with the whitespace. Thanks.
However the optimization flag is ignored and individual optimization flags like -finline-small-functions or -fprefetch-loop-arrays are rejected as invalid.
I want to experiment with them and find one that optimizes hash functions for strings (to use with the switch statement).
Can they be whitelisted?

Description	Resource	Path	Location	Type
Invalid flag in extension 'openal' - 'flags': '-finline-small-functions'	ext.manifest	/extension-openal/content/openal	line 1	Problem
1 Like

Ah, great that it worked!
(@mikael.lothman did we create a ticket for that issue? I know I forgot to do it ;))

Yes we can whitelist them (I’m away on vacation right now, but perhaps @sven can add them?)

Also, regarding compiler optimisations, I can highly recommend https://godbolt.org/ for testing implementations and flags, in order to see what gives the best output (disassembly). I use it a lot :slight_smile:

5 Likes

The manifest format is YAML, and YAML doesn’t support tabs. If you mix tabs and spaces for indentation in the same file, it’s hard to interpret that file in a safe way. I think the best solution would be to alert in the editor if you try to use tabs in YAML-files. @sergey.lerg I will follow up on this and let you know once we have agreed on a solution.

6 Likes

Holy crap! That’s a cool service!

3 Likes