Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiling with emscripten #128

Open
abeimler opened this issue Jun 19, 2024 · 3 comments
Open

Compiling with emscripten #128

abeimler opened this issue Jun 19, 2024 · 3 comments

Comments

@abeimler
Copy link
Contributor

Hi,

I am experiencing a compiler error when using emscripten (compiling to wasm) since the latest update.

In file included from libs/fixed_containers/include/fixed_containers/fixed_circular_deque.hpp:4:
In file included from libs/fixed_containers/include/fixed_containers/fixed_deque.hpp:14:
libs/fixed_containers/include/fixed_containers/random_access_iterator.hpp:171:37: error: no member named 'iterator_' in 'RandomAccessIterator<ConstEntryProvider, MutableEntryProvider, CONSTNESS, DIRECTION>'
  171 |         return Self(std::next(other.iterator_, n));
      |                               ~~~~~ ^
1 error generated.

Looking into RandomAccessIterator<ConstEntryProvider, MutableEntryProvider, CONSTNESS, DIRECTION>, it appears that iterator_ is not a member. This raises the question of why it compiles successfully with gcc.

Notes:

  • Compiler: emcc/emc++ 3.1.61 emsdk up-to-date from git
  • Compiler: gcc 14.1.1 (compiles successfully)
  • CMake: 3.28.1
  • OS: Arch Linux (Kernel: 6.9.5)
/bin/ccache /usr/lib/emscripten/em++ -isystem vcpkg_installed/wasm32-emscripten/include ... -Os -DNDEBUG -std=c++20 -fcolor-diagnostics -fcolor-diagnostics -Wall ... -MD -MT ...

some warnings and include paths, but nothing special

I has not set up or cross-compiled the fixed-containers project itself with emcc; this issue arises in my other projects that build with emcc. The compilation works fine with gcc, but not for the web build.

This issue occurs with a personal fork of fixed-containers, which is up-to-date with the current main branch.

@abeimler
Copy link
Contributor Author

I tried to compile my fixed-containers branch with emscripten and get this errors:

CMake Options:

-DENABLE_TESTING:BOOL=ON
-DENABLE_CROSS_COMPILING:BOOL=ON
-DDEFAULT_TRIPLET=wasm32-emscripten
-DEMSCRIPTEN_ROOT_PATH:STRING=/usr/lib/emscripten
-DCMAKE_C_COMPILER:STRING=/usr/lib/emscripten/emcc
-DCMAKE_CXX_COMPILER:STRING=/usr/lib/emscripten/em++
-DEMSCRIPTEN_VERSION:STRING=3.1.44
-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE:STRING=/usr/lib/emscripten/cmake/Modules/Platform/Emscripten.cmake
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=/usr/lib/emscripten/emcc -DCMAKE_CXX_COMPILER=/usr/lib/emscripten/em++ -DENABLE_TESTING:BOOL=ON -DENABLE_CROSS_COMPILING:BOOL=ON -DDEFAULT_TRIPLET=wasm32-emscripten -DEMSCRIPTEN_ROOT_PATH:STRING=/usr/lib/emscripten -DCMAKE_C_COMPILER:STRING=/usr/lib/emscripten/emcc -DCMAKE_CXX_COMPILER:STRING=/usr/lib/emscripten/em++ -DEMSCRIPTEN_VERSION:STRING=3.1.44 -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE:STRING=/usr/lib/emscripten/cmake/Modules/Platform/Emscripten.cmake -G Ninja -S fixed-containers -B fixed-containers/cmake-build-debug-web
-- CPM: Adding package project_options@0.35.1 (v0.35.1)
-- Unknown architecture  - using x64
-- fetch emscripten repo main branch. ...
-- enable cross-compiling
-- use emscripten cross-compiling
-- use emscripten cross-compiler emulator: ;--experimental-wasm-threads
-- Target Architecture: wasm32-emscripten
-- Default Triplet: wasm32-emscripten
-- Host Triplet: x64-linux
-- Setup cross-compiler for wasm32-emscripten
-- Use cross-compiler toolchain for vcpkg: /usr/lib/emscripten/cmake/Modules/Platform/Emscripten.cmake
-- Running vcpkg install
Detecting compiler hash for triplet x64-linux...
Detecting compiler hash for triplet wasm32-emscripten...
All requested packages are currently installed.
FAILED: test/CMakeFiles/circular_integer_range_iterator_test.dir/circular_integer_range_iterator_test.cpp.o 
/bin/ccache /usr/lib/emscripten/em++ -DFIXED_CONTAINERS_IOSTREAM_SUPPORT -Ifixed-containers/include -isystem fixed-containers/cmake-build-debug-web/vcpkg_installed/wasm32-emscripten/include -g -std=c++20 -fcolor-diagnostics -fcolor-diagnostics -fno-sanitize-recover=all -fsanitize=address,undefined -fno-exceptions -ftemplate-backtrace-limit=0 -ftrivial-auto-var-init=pattern -Weverything -Wno-c++98-compat-pedantic -Wc++98-compat-extra-semi -Wno-weak-template-vtables -Wno-global-constructors -Wno-range-loop-bind-reference -Wno-covered-switch-default -Wno-switch-default -Wno-exit-time-destructors -Wno-used-but-marked-unused -Wno-c++20-compat -Wno-ctad-maybe-unsupported -Wno-padded -Wno-poison-system-directories -MD -MT test/CMakeFiles/circular_integer_range_iterator_test.dir/circular_integer_range_iterator_test.cpp.o -MF test/CMakeFiles/circular_integer_range_iterator_test.dir/circular_integer_range_iterator_test.cpp.o.d -o test/CMakeFiles/circular_integer_range_iterator_test.dir/circular_integer_range_iterator_test.cpp.o -c fixed-containers/test/circular_integer_range_iterator_test.cpp
In file included from fixed-containers/test/circular_integer_range_iterator_test.cpp:1:
In file included from fixed-containers/include/fixed_containers/circular_integer_range_iterator.hpp:8:
fixed-containers/include/fixed_containers/random_access_iterator.hpp:171:37: error: no member named 'iterator_' in 'RandomAccessIterator<ConstEntryProvider, MutableEntryProvider, CONSTNESS, DIRECTION>'
  171 |         return Self(std::next(other.iterator_, n));
      |                               ~~~~~ ^
fixed-containers/test/circular_integer_range_iterator_test.cpp:15:15: error: static assertion failed due to requirement 'sizeof(fixed_containers::RandomAccessIterator<fixed_containers::CircularIntegerRangeEntryProvider<fixed_containers::IntegerRange>, fixed_containers::CircularIntegerRangeEntryProvider<fixed_containers::IntegerRange>, fixed_containers::IteratorConstness::CONSTANT_ITERATOR, fixed_containers::IteratorDirection::FORWARD>) == 32'
   15 | static_assert(sizeof(CircularIntegerRangeIterator<IteratorDirection::FORWARD, IntegerRange>) == 32);
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fixed-containers/test/circular_integer_range_iterator_test.cpp:15:94: note: expression evaluates to '24 == 32'
   15 | static_assert(sizeof(CircularIntegerRangeIterator<IteratorDirection::FORWARD, IntegerRange>) == 32);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
fixed-containers/test/circular_integer_range_iterator_test.cpp:183:9: error: use of undeclared identifier 'EXPECT_DEATH'
  183 |         EXPECT_DEATH(void(it1 != it3), "");  // Hard error if attempting to compare unrelated ranges
      |         ^
3 errors generated.
[2/87] Building CXX object test/CMakeFiles/fixed_circular_queue_test.dir/fixed_circular_queue_test.cpp.o
FAILED: test/CMakeFiles/fixed_circular_queue_test.dir/fixed_circular_queue_test.cpp.o 
/bin/ccache /usr/lib/emscripten/em++ -DFIXED_CONTAINERS_IOSTREAM_SUPPORT -Ifixed-containers/include -isystem fixed-containers/cmake-build-debug-web/vcpkg_installed/wasm32-emscripten/include -g -std=c++20 -fcolor-diagnostics -fcolor-diagnostics -fno-sanitize-recover=all -fsanitize=address,undefined -fno-exceptions -ftemplate-backtrace-limit=0 -ftrivial-auto-var-init=pattern -Weverything -Wno-c++98-compat-pedantic -Wc++98-compat-extra-semi -Wno-weak-template-vtables -Wno-global-constructors -Wno-range-loop-bind-reference -Wno-covered-switch-default -Wno-switch-default -Wno-exit-time-destructors -Wno-used-but-marked-unused -Wno-c++20-compat -Wno-ctad-maybe-unsupported -Wno-padded -Wno-poison-system-directories -MD -MT test/CMakeFiles/fixed_circular_queue_test.dir/fixed_circular_queue_test.cpp.o -MF test/CMakeFiles/fixed_circular_queue_test.dir/fixed_circular_queue_test.cpp.o.d -o test/CMakeFiles/fixed_circular_queue_test.dir/fixed_circular_queue_test.cpp.o -c fixed-containers/test/fixed_circular_queue_test.cpp
In file included from fixed-containers/test/fixed_circular_queue_test.cpp:1:
In file included from fixed-containers/include/fixed_containers/fixed_circular_queue.hpp:4:
In file included from fixed-containers/include/fixed_containers/fixed_circular_deque.hpp:4:
In file included from fixed-containers/include/fixed_containers/fixed_deque.hpp:14:
fixed-containers/include/fixed_containers/random_access_iterator.hpp:171:37: error: no member named 'iterator_' in 'RandomAccessIterator<ConstEntryProvider, MutableEntryProvider, CONSTNESS, DIRECTION>'
  171 |         return Self(std::next(other.iterator_, n));
      |                               ~~~~~ ^
1 error generated.
[3/87] Building CXX object test/CMakeFiles/filtered_integer_range_iterator_test.dir/filtered_integer_range_iterator_test.cpp.o
FAILED: test/CMakeFiles/filtered_integer_range_iterator_test.dir/filtered_integer_range_iterator_test.cpp.o 
/bin/ccache /usr/lib/emscripten/em++ -DFIXED_CONTAINERS_IOSTREAM_SUPPORT -Ifixed-containers/include -isystem fixed-containers/cmake-build-debug-web/vcpkg_installed/wasm32-emscripten/include -g -std=c++20 -fcolor-diagnostics -fcolor-diagnostics -fno-sanitize-recover=all -fsanitize=address,undefined -fno-exceptions -ftemplate-backtrace-limit=0 -ftrivial-auto-var-init=pattern -Weverything -Wno-c++98-compat-pedantic -Wc++98-compat-extra-semi -Wno-weak-template-vtables -Wno-global-constructors -Wno-range-loop-bind-reference -Wno-covered-switch-default -Wno-switch-default -Wno-exit-time-destructors -Wno-used-but-marked-unused -Wno-c++20-compat -Wno-ctad-maybe-unsupported -Wno-padded -Wno-poison-system-directories -MD -MT test/CMakeFiles/filtered_integer_range_iterator_test.dir/filtered_integer_range_iterator_test.cpp.o -MF test/CMakeFiles/filtered_integer_range_iterator_test.dir/filtered_integer_range_iterator_test.cpp.o.d -o test/CMakeFiles/filtered_integer_range_iterator_test.dir/filtered_integer_range_iterator_test.cpp.o -c fixed-containers/test/filtered_integer_range_iterator_test.cpp
fixed-containers/test/filtered_integer_range_iterator_test.cpp:63:15: error: static assertion failed due to requirement 'sizeof(fixed_containers::BidirectionalIterator<fixed_containers::FilteredIntegerRangeEntryProvider<fixed_containers::(anonymous namespace)::AlwaysTruePredicate, fixed_containers::IntegerRange>, fixed_containers::FilteredIntegerRangeEntryProvider<fixed_containers::(anonymous namespace)::AlwaysTruePredicate, fixed_containers::IntegerRange>, fixed_containers::IteratorConstness::CONSTANT_ITERATOR, fixed_containers::IteratorDirection::FORWARD>) == 32'
   63 | static_assert(sizeof(FilteredIntegerRangeIterator<AlwaysTruePredicate,
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   64 |                                                   IteratorDirection::FORWARD,
      |                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   65 |                                                   IntegerRange>) == 32);
      |                                                   ~~~~~~~~~~~~~~~~~~~~
fixed-containers/test/filtered_integer_range_iterator_test.cpp:65:66: note: expression evaluates to '16 == 32'
   63 | static_assert(sizeof(FilteredIntegerRangeIterator<AlwaysTruePredicate,
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   64 |                                                   IteratorDirection::FORWARD,
      |                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   65 |                                                   IntegerRange>) == 32);
      |                                                   ~~~~~~~~~~~~~~~^~~~~
fixed-containers/test/filtered_integer_range_iterator_test.cpp:66:15: error: static assertion failed due to requirement 'sizeof(fixed_containers::BidirectionalIterator<fixed_containers::FilteredIntegerRangeEntryProvider<fixed_containers::(anonymous namespace)::AlwaysTruePredicate, fixed_containers::CompileTimeIntegerRange<0, 3>>, fixed_containers::FilteredIntegerRangeEntryProvider<fixed_containers::(anonymous namespace)::AlwaysTruePredicate, fixed_containers::CompileTimeIntegerRange<0, 3>>, fixed_containers::IteratorConstness::CONSTANT_ITERATOR, fixed_containers::IteratorDirection::FORWARD>) == 16'
   66 | static_assert(sizeof(FilteredIntegerRangeIterator<AlwaysTruePredicate,
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   67 |                                                   IteratorDirection::FORWARD,
      |                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   68 |                                                   CompileTimeIntegerRange<0, 3>>) == 16);
      |                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fixed-containers/test/filtered_integer_range_iterator_test.cpp:68:83: note: expression evaluates to '8 == 16'
   66 | static_assert(sizeof(FilteredIntegerRangeIterator<AlwaysTruePredicate,
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   67 |                                                   IteratorDirection::FORWARD,
      |                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   68 |                                                   CompileTimeIntegerRange<0, 3>>) == 16);
      |                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
fixed-containers/test/filtered_integer_range_iterator_test.cpp:69:15: error: static assertion failed due to requirement 'sizeof(fixed_containers::BidirectionalIterator<fixed_containers::FilteredIntegerRangeEntryProvider<fixed_containers::(anonymous namespace)::SpecificValuePredicate, fixed_containers::CompileTimeIntegerRange<0, 3>>, fixed_containers::FilteredIntegerRangeEntryProvider<fixed_containers::(anonymous namespace)::SpecificValuePredicate, fixed_containers::CompileTimeIntegerRange<0, 3>>, fixed_containers::IteratorConstness::CONSTANT_ITERATOR, fixed_containers::IteratorDirection::FORWARD>) == 24'
   69 | static_assert(sizeof(FilteredIntegerRangeIterator<SpecificValuePredicate,
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   70 |                                                   IteratorDirection::FORWARD,
      |                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   71 |                                                   CompileTimeIntegerRange<0, 3>>) == 24);
      |                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fixed-containers/test/filtered_integer_range_iterator_test.cpp:71:83: note: expression evaluates to '12 == 24'
   69 | static_assert(sizeof(FilteredIntegerRangeIterator<SpecificValuePredicate,
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   70 |                                                   IteratorDirection::FORWARD,
      |                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   71 |                                                   CompileTimeIntegerRange<0, 3>>) == 24);
      |                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
In file included from fixed-containers/test/filtered_integer_range_iterator_test.cpp:1:
In file included from fixed-containers/include/fixed_containers/filtered_integer_range_iterator.hpp:4:
fixed-containers/include/fixed_containers/bidirectional_iterator.hpp:79:57: warning: implicit conversion loses integer precision: 'unsigned long long' to 'std::size_t' (aka 'unsigned long') [-Wshorten-64-to-32]
   79 |       : reference_provider_(std::forward<First>(first), std::forward<Args>(args)...)
      |         ~~~~~~~~~~~~~~~~~~~                             ^~~~~~~~~~~~~~~~~~~~~~~~
fixed-containers/test/filtered_integer_range_iterator_test.cpp:91:26: note: in instantiation of function template specialization 'fixed_containers::BidirectionalIterator<fixed_containers::FilteredIntegerRangeEntryProvider<fixed_containers::(anonymous namespace)::AlwaysTruePredicate>, fixed_containers::FilteredIntegerRangeEntryProvider<fixed_containers::(anonymous namespace)::AlwaysTruePredicate>, fixed_containers::IteratorConstness::CONSTANT_ITERATOR, fixed_containers::IteratorDirection::FORWARD>::BidirectionalIterator<fixed_containers::IntegerRange, unsigned long long, fixed_containers::(anonymous namespace)::AlwaysTruePredicate>' requested here
   91 |         constexpr ItType it{IntegerRange::closed_open(0, 3), 0ULL, AlwaysTruePredicate{}};
      |                          ^

I do not expect to run the tests fully in wasm, just a quick test for the build.

alexkaratarakis added a commit to alexkaratarakis/fixed-containers that referenced this issue Jun 20, 2024
Expose by teslamotors#128

This was previously building without issue due to two-phase lookup and
the function never being called. New units tests will instantiate
this function.

```C++
template <class T>
struct MockTemplate
{
    int foo(const MockTemplate<T>& input) const { return input.variable_that_does_not_exist; }
};

int main()
{
    MockTemplate<int> it{};
    (void)it;
    // it.foo(it);
}

```
alexkaratarakis added a commit to alexkaratarakis/fixed-containers that referenced this issue Jun 20, 2024
Exposed by teslamotors#128

This was previously building without issue due to two-phase lookup and
the function never being called. New units tests will instantiate
this function.

```C++
template <class T>
struct MockTemplate
{
    int foo(const MockTemplate<T>& input) const { return input.variable_that_does_not_exist; }
};

int main()
{
    MockTemplate<int> it{};
    (void)it;
    // it.foo(it);
}

```
@alexkaratarakis
Copy link
Collaborator

alexkaratarakis commented Jun 20, 2024

This is caused by two phase-lookup and the function not being used/instantiated. This allows the build to succeed in msvc/gcc/clang because they never actually attempt to instantiate the function. Here is a simple example that compiles even though it references a variable that doesn't exist:

template <class T>
struct MockTemplate
{
    int foo(const MockTemplate<T>& input) const { return input.variable_that_does_not_exist; }
};

int main()
{
    MockTemplate<int> it{};
    (void)it;
    // it.foo(it);
}

I am guessing emscripten tries to instantiate everything instead, hitting the issue immediately. The above example should also fail to compile with emscripten.

I have a fix for the reported issue. The PR also adds unit tests that instantiate the function and highlight the non-existent variable.

alexkaratarakis added a commit to alexkaratarakis/fixed-containers that referenced this issue Jun 20, 2024
Exposed by teslamotors#128

This was previously building without issue due to two-phase lookup and
the function never being called. New units tests will instantiate
this function.

```C++
template <class T>
struct MockTemplate
{
    int foo(const MockTemplate<T>& input) const { return input.variable_that_does_not_exist; }
};

int main()
{
    MockTemplate<int> it{};
    (void)it;
    // it.foo(it);
}

```
@abeimler
Copy link
Contributor Author

Thanks for the quick fix,
I recompiled the fixed-container with emscripten and it seems to work, the only expected errors:

fixed-containers/test/circular_integer_range_iterator_test.cpp:18:15: error: static assertion failed due to requirement 'sizeof(fixed_containers::RandomAccessIterator<fixed_containers::CircularIntegerRangeEntryProvider<fixed_containers::IntegerRange>, fixed_containers::CircularIntegerRangeEntryProvider<fixed_containers::IntegerRange>, fixed_containers::IteratorConstness::CONSTANT_ITERATOR, fixed_containers::IteratorDirection::FORWARD>) == 32'
   18 | static_assert(sizeof(CircularIntegerRangeIterator<IteratorDirection::FORWARD, IntegerRange>) == 32);
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fixed-containers/test/circular_integer_range_iterator_test.cpp:18:94: note: expression evaluates to '24 == 32'
   18 | static_assert(sizeof(CircularIntegerRangeIterator<IteratorDirection::FORWARD, IntegerRange>) == 32);
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
fixed-containers/test/circular_integer_range_iterator_test.cpp:186:9: error: use of undeclared identifier 'EXPECT_DEATH'
  186 |         EXPECT_DEATH(void(it1 != it3), "");  // Hard error if attempting to compare unrelated ranges
      |         ^

I also recompiled my other Project with emscripten, no build errors. 👍

EazyReal pushed a commit to EazyReal/fixed-containers that referenced this issue Jul 16, 2024
Exposed by teslamotors#128

This was previously building without issue due to two-phase lookup and
the function never being called. New units tests will instantiate
this function.

```C++
template <class T>
struct MockTemplate
{
    int foo(const MockTemplate<T>& input) const { return input.variable_that_does_not_exist; }
};

int main()
{
    MockTemplate<int> it{};
    (void)it;
    // it.foo(it);
}

```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants