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

Can't build samples on Visual Studio 2015 #699

Open
guilms opened this issue Apr 5, 2022 · 9 comments
Open

Can't build samples on Visual Studio 2015 #699

guilms opened this issue Apr 5, 2022 · 9 comments
Labels
enhancement New feature or request portability Run on more platforms

Comments

@guilms
Copy link

guilms commented Apr 5, 2022

The library compiles properly with Visual Studio 2015, but simple samples like examples/cpp/hello_world/src/main.cpp won't compile with vs2015.

The code:

#include "flecs.h"

#include "stdafx.h"

// Component types
struct Position {
    double x;
    double y;
};

struct Velocity {
    double x;
    double y;
};

// Tag types
struct Eats { };
struct Apples { };

int main(int, char *[]) {
    // Create the world
    flecs::world ecs;

    // Register system
    ecs.system<Position, Velocity>()
        .each([](Position& p, Velocity& v) {
        p.x += v.x;
        p.y += v.y;
    });

    // Create an entity with name Bob, add Position and food preference
    auto Bob = ecs.entity("Bob")
        .set(Position{ 0, 0 })
        .set(Velocity{ 1, 2 })
        .add<Eats, Apples>();

    // Show us what you got
    printf("%s's got: [%s]\n", Bob.name().c_str(), Bob.type().str().c_str());

    // Run systems twice. Usually this function is called once per frame
    ecs.progress();
    ecs.progress();

    // See if Bob has moved (he has)
    const Position *p = Bob.get<Position>();
    printf("Bob's position is {%f, %f}\n", p->x, p->y);
}

The compiler errors:

1>d:\testflecs\testflecs.cpp(38): error C2672: 'flecs::entity_builder<flecs::entity>::add': no matching overloaded function found
1>d:\testflecs\testflecs.cpp(38): error C2977: 'flecs::entity_builder<flecs::entity>::add': too many template arguments
1>  d:\devel\vortextoolkit\3rdparty\flecs\x64_win32_vc14\include\flecs\flecs.hpp(1249): note: see declaration of 'flecs::entity_builder<flecs::entity>::add'
1>d:\testflecs\testflecs.cpp(41): error C3536: 'Bob': cannot be used before it is initialized
1>d:\testflecs\testflecs.cpp(41): error C2228: left of '.name' must have class/struct/union
1>  d:\testflecs\testflecs.cpp(41): note: type is 'int'
1>d:\testflecs\testflecs.cpp(41): error C2228: left of '.c_str' must have class/struct/union
1>d:\testflecs\testflecs.cpp(41): error C2228: left of '.type' must have class/struct/union
1>  d:\testflecs\testflecs.cpp(41): note: type is 'int'
1>d:\testflecs\testflecs.cpp(41): error C2228: left of '.str' must have class/struct/union
1>d:\testflecs\testflecs.cpp(48): error C2228: left of '.get' must have class/struct/union
1>  d:\testflecs\testflecs.cpp(48): note: type is 'int'
1>d:\testflecs\testflecs.cpp(48): error C2059: syntax error: ')'
1>d:\testflecs\testflecs.cpp(41): warning C4473: 'printf' : not enough arguments passed for format string
1>  d:\testflecs\testflecs.cpp(41): note: placeholders and their parameters expect 2 variadic arguments, but 0 were provided
1>  d:\testflecs\testflecs.cpp(41): note: the missing variadic argument 1 is required by format string '%s'

Steps to reproduce the behavior

  1. checkout master
  2. build and install with visual studio 2015
  3. create a new vs2015 project with examples/cpp/hello_world/src/main.cpp file
  4. Compile

Expected behavior
All the samples should compile on visual studio 2015

Notes

@guilms guilms added the bug Something isn't working label Apr 5, 2022
@SanderMertens
Copy link
Owner

SanderMertens commented Apr 5, 2022

Hm, it looks like examples are building in CI:
https://github.com/SanderMertens/flecs/runs/5839369469?check_suite_focus=true

Thinking about what could cause this, are you compiling code as C++11 (or higher)?

@SanderMertens SanderMertens added the portability Run on more platforms label Apr 5, 2022
@SanderMertens
Copy link
Owner

This error:

1>d:\testflecs\testflecs.cpp(38): error C2672: 'flecs::entity_builder<flecs::entity>::add': no matching overloaded function found
1>d:\testflecs\testflecs.cpp(38): error C2977: 'flecs::entity_builder<flecs::entity>::add': too many template arguments

does look like something you'd get when you're trying to compile a v3 example (like the one posted) with the v2 API, can you confirm you're using the v3 library?

@guilms
Copy link
Author

guilms commented Apr 5, 2022

I double checked and I compiled v3. The sample works on vs 2019 but not 2015. Visual Studio 2015 uses C++ 14.
It looks like the CI is using visual studio 2022
image

@SanderMertens
Copy link
Owner

Hm, are you sure sure? :p

Looking at the error message:

1>  d:\devel\vortextoolkit\3rdparty\flecs\x64_win32_vc14\include\flecs\flecs.hpp(1249):

In v3 flecs.hpp is just a file that includes the rest of the C++ API, and only has 144 lines. The entity builder code is here: https://github.com/SanderMertens/flecs/blob/master/include/flecs/addons/cpp/mixins/entity/builder.hpp

@guilms
Copy link
Author

guilms commented Apr 5, 2022

My bad! I mixed the configurations in the configuration manager. These are the errors I was getting in the first place before mixing configurations :

1>c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(178): error C2672: 'flecs::_::enum_type<E>::init_constant': no matching overloaded function found
1>          with
1>          [
1>              E=ecs_primitive_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(139): note: see reference to function template instantiation 'void flecs::_::enum_type<E>::init<17>(flecs::world_t *)' being compiled
1>          with
1>          [
1>              E=ecs_primitive_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(139): note: see reference to function template instantiation 'void flecs::_::enum_type<E>::init<17>(flecs::world_t *)' being compiled
1>          with
1>          [
1>              E=ecs_primitive_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(128): note: while compiling class template member function 'void flecs::_::enum_type<E>::init(flecs::world_t *,flecs::entity_t)'
1>          with
1>          [
1>              E=ecs_primitive_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(190): note: see reference to function template instantiation 'void flecs::_::enum_type<E>::init(flecs::world_t *,flecs::entity_t)' being compiled
1>          with
1>          [
1>              E=ecs_primitive_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(190): note: see reference to class template instantiation 'flecs::_::enum_type<E>' being compiled
1>          with
1>          [
1>              E=ecs_primitive_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(186): note: see reference to function template instantiation 'void flecs::_::init_enum<T,0>(flecs::world_t *,flecs::entity_t)' being compiled
1>          with
1>          [
1>              T=ecs_primitive_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(157): note: while compiling class template member function 'flecs::entity_t flecs::_::cpp_type_impl<ecs_primitive_kind_t>::id_explicit(flecs::world_t *,const char *,bool,flecs::id_t,bool)'
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(364): note: see reference to function template instantiation 'flecs::entity_t flecs::_::cpp_type_impl<ecs_primitive_kind_t>::id_explicit(flecs::world_t *,const char *,bool,flecs::id_t,bool)' being compiled
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(306): note: see reference to class template instantiation 'flecs::_::cpp_type_impl<ecs_primitive_kind_t>' being compiled
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(361): note: see reference to class template instantiation 'flecs::_::cpp_type<T,int>' being compiled
1>          with
1>          [
1>              T=flecs::primitive_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(341): note: while compiling class template member function 'flecs::component<flecs::primitive_kind_t>::component(flecs::world_t *,const char *,bool,flecs::id_t)'
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\mixins\component\impl.hpp(8): note: see reference to function template instantiation 'flecs::component<flecs::primitive_kind_t>::component(flecs::world_t *,const char *,bool,flecs::id_t)' being compiled
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\mixins\meta\impl.hpp(25): note: see reference to class template instantiation 'flecs::component<flecs::primitive_kind_t>' being compiled
1>c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(178): error C2783: 'void flecs::_::enum_type<E>::init_constant(flecs::world_t *)': could not deduce template argument for '__formal'
1>          with
1>          [
1>              E=ecs_primitive_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(163): note: see declaration of 'flecs::_::enum_type<E>::init_constant'
1>          with
1>          [
1>              E=ecs_primitive_kind_t
1>          ]
1>c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(178): error C2672: 'flecs::_::enum_type<E>::init_constant': no matching overloaded function found
1>          with
1>          [
1>              E=ecs_type_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(139): note: see reference to function template instantiation 'void flecs::_::enum_type<E>::init<5>(flecs::world_t *)' being compiled
1>          with
1>          [
1>              E=ecs_type_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(139): note: see reference to function template instantiation 'void flecs::_::enum_type<E>::init<5>(flecs::world_t *)' being compiled
1>          with
1>          [
1>              E=ecs_type_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(128): note: while compiling class template member function 'void flecs::_::enum_type<E>::init(flecs::world_t *,flecs::entity_t)'
1>          with
1>          [
1>              E=ecs_type_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(190): note: see reference to function template instantiation 'void flecs::_::enum_type<E>::init(flecs::world_t *,flecs::entity_t)' being compiled
1>          with
1>          [
1>              E=ecs_type_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(190): note: see reference to class template instantiation 'flecs::_::enum_type<E>' being compiled
1>          with
1>          [
1>              E=ecs_type_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(186): note: see reference to function template instantiation 'void flecs::_::init_enum<T,0>(flecs::world_t *,flecs::entity_t)' being compiled
1>          with
1>          [
1>              T=ecs_type_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(157): note: while compiling class template member function 'flecs::entity_t flecs::_::cpp_type_impl<ecs_type_kind_t>::id_explicit(flecs::world_t *,const char *,bool,flecs::id_t,bool)'
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(364): note: see reference to function template instantiation 'flecs::entity_t flecs::_::cpp_type_impl<ecs_type_kind_t>::id_explicit(flecs::world_t *,const char *,bool,flecs::id_t,bool)' being compiled
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(306): note: see reference to class template instantiation 'flecs::_::cpp_type_impl<ecs_type_kind_t>' being compiled
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(361): note: see reference to class template instantiation 'flecs::_::cpp_type<T,int>' being compiled
1>          with
1>          [
1>              T=flecs::type_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\component.hpp(341): note: while compiling class template member function 'flecs::component<flecs::type_kind_t>::component(flecs::world_t *,const char *,bool,flecs::id_t)'
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\mixins\component\impl.hpp(8): note: see reference to function template instantiation 'flecs::component<flecs::type_kind_t>::component(flecs::world_t *,const char *,bool,flecs::id_t)' being compiled
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\mixins\meta\impl.hpp(24): note: see reference to class template instantiation 'flecs::component<flecs::type_kind_t>' being compiled
1>c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(178): error C2783: 'void flecs::_::enum_type<E>::init_constant(flecs::world_t *)': could not deduce template argument for '__formal'
1>          with
1>          [
1>              E=ecs_type_kind_t
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\enum.hpp(163): note: see declaration of 'flecs::_::enum_type<E>::init_constant'
1>          with
1>          [
1>              E=ecs_type_kind_t
1>          ]
1>  stdafx.cpp

@SanderMertens
Copy link
Owner

The errors are a bit obtuse, but what I think is happening is that vs2015 has a different format for __FUNCTION__ than later versions.

The enum reflection code uses that macro + a function that accepts the enum value as a template parameter to figure out the name of the constant at compile time. There is a bit of (ugly but it works) trickery to figure out from that string whether value is a valid constant for the enumeration.

If this is what is happening (I can't validate yet, don't have a vs2015 environment setup) I'd have to special case that version of msvc with whatever format it uses for __FUNCTION__.

If you'd like to take a crack at it let me know & I can point you to the right code. Alternatively you could also remove the enum.hpp header from the library code (iirc there is only one reference to it from component.hpp), as this functionality is only used to automatically register constants for enum types.

@guilms
Copy link
Author

guilms commented Apr 6, 2022

Hi,
I haven't found __FUNCTION__ references in the project, but I found __FUNCSIG__ in flecs_cpp.h.

I created a test to compare this macros and others between Visual Studio 2015 and 2019.
I'm getting the exact same result for these macros in vs2015 and vs2019 :

__FUNCTION__ : MyClass::PrintInfo
__func__ : PrintInfo
__FUNCDNAME__ : ?PrintInfo@MyClass@@QAEXXZ
__FUNCSIG__ : void __thiscall MyClass::PrintInfo(void)

I also tried to remove the enum header and its references, but I'm now getting this error:

1>------ Build started: Project: TestFlecs, Configuration: Debug x64 ------
1>  TestFlecs.cpp
1>c:\program files (x86)\flecs\include\flecs\addons\cpp\invoker.hpp(263): error C2672: 'flecs::_::each_invoker<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>,Position,Velocity>::invoke_callback': no matching overloaded function found
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\invoker.hpp(263): note: see reference to function template instantiation 'void flecs::_::each_invoker<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>,Position,Velocity>::invoke_callback<ColumnType,T,0>(ecs_iter_t *,const Func &,std::size_t,flecs::array<T,2,void> &,T)' being compiled
1>          with
1>          [
1>              ColumnType=flecs::_::each_ref_column,
1>              T=flecs::_::term_ptr,
1>              Func=main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\invoker.hpp(262): note: see reference to function template instantiation 'void flecs::_::each_invoker<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>,Position,Velocity>::invoke_callback<ColumnType,T,0>(ecs_iter_t *,const Func &,std::size_t,flecs::array<T,2,void> &,T)' being compiled
1>          with
1>          [
1>              ColumnType=flecs::_::each_ref_column,
1>              T=flecs::_::term_ptr,
1>              Func=main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\invoker.hpp(179): note: see reference to function template instantiation 'void flecs::_::each_invoker<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>,Position,Velocity>::invoke_callback<flecs::_::each_ref_column,,0>(ecs_iter_t *,const Func &,std::size_t,flecs::array<flecs::_::term_ptr,2,void> &)' being compiled
1>          with
1>          [
1>              Func=main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\invoker.hpp(179): note: see reference to function template instantiation 'void flecs::_::each_invoker<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>,Position,Velocity>::invoke_callback<flecs::_::each_ref_column,,0>(ecs_iter_t *,const Func &,std::size_t,flecs::array<flecs::_::term_ptr,2,void> &)' being compiled
1>          with
1>          [
1>              Func=main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\invoker.hpp(175): note: while compiling class template member function 'void flecs::_::each_invoker<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>,Position,Velocity>::invoke(ecs_iter_t *) const'
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\invoker.hpp(189): note: see reference to function template instantiation 'void flecs::_::each_invoker<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>,Position,Velocity>::invoke(ecs_iter_t *) const' being compiled
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\node_builder.hpp(54): note: see reference to class template instantiation 'flecs::_::each_invoker<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>,Position,Velocity>' being compiled
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\node_builder.hpp(42): note: see reference to function template instantiation 'T flecs::_::node_builder<T,ecs_system_desc_t,flecs::system_builder<Position,Velocity>,flecs::system_builder_i,Position,Velocity>::build<Invoker,Func>(Func &&)' being compiled
1>          with
1>          [
1>              T=flecs::system,
1>              Func=main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>
1>          ]
1>  c:\program files (x86)\flecs\include\flecs\addons\cpp\utils\node_builder.hpp(42): note: see reference to function template instantiation 'T flecs::_::node_builder<T,ecs_system_desc_t,flecs::system_builder<Position,Velocity>,flecs::system_builder_i,Position,Velocity>::build<Invoker,Func>(Func &&)' being compiled
1>          with
1>          [
1>              T=flecs::system,
1>              Func=main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>
1>          ]
1>  d:\devel\testflecs\testflecs\testflecs.cpp(32): note: see reference to function template instantiation 'T flecs::_::node_builder<T,ecs_system_desc_t,flecs::system_builder<Position,Velocity>,flecs::system_builder_i,Position,Velocity>::each<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>>(Func &&)' being compiled
1>          with
1>          [
1>              T=flecs::system,
1>              Func=main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>
1>          ]
1>  d:\devel\testflecs\testflecs\testflecs.cpp(29): note: see reference to function template instantiation 'T flecs::_::node_builder<T,ecs_system_desc_t,flecs::system_builder<Position,Velocity>,flecs::system_builder_i,Position,Velocity>::each<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>>(Func &&)' being compiled
1>          with
1>          [
1>              T=flecs::system,
1>              Func=main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>
1>          ]
1>c:\program files (x86)\flecs\include\flecs\addons\cpp\invoker.hpp(263): error C2783: 'void flecs::_::each_invoker<main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>,Position,Velocity>::invoke_callback(ecs_iter_t *,const Func &,std::size_t,flecs::array<flecs::_::term_ptr,2,void> &,Args...)': could not deduce template argument for '__formal'
1>          with
1>          [
1>              Func=main::<lambda_dd5e9471859c503e68cc9a6417c7f4c9>
1>          ]

Any other idea?

Thank you!

@SanderMertens SanderMertens added enhancement New feature or request and removed bug Something isn't working labels Apr 13, 2022
@RPGHacker
Copy link

Have there ever been any new discoveries on this issue? I'm currently trying to evaluate flecs for a work-related project, and VS 2015 is the newest version usable by us right now. I'm running into the same issues as mentioned in #699 (comment). Removing the enum.hpp header didn't resolve them.

I tried using the C API instead of the C++ API, but that didn't work, since it's written in a way that makes it only compile from native C code, not C++. I even switched back to an old 2.x version of flecs to see if I'd get any further with that, but it pretty much just led to a different set of template-related errors. So currently, I think I'm pretty much out of options for stuff I could try, at least until we are able to work with a newer VS version.

@SanderMertens
Copy link
Owner

SanderMertens commented May 4, 2023

@RPGHacker I added a new FLECS_CPP_ENUM_REFLECTION_SUPPORT macro that allows you to disable automatic enum reflection by adding this define:

#define FLECS_CPP_ENUM_REFLECTION_SUPPORT 0

I tried using the C API instead of the C++ API, but that didn't work, since it's written in a way that makes it only compile from native C code, not C++

You should be able to use the C API from C++ (the C++ API is written using the C API). Some shorthand macro's (e.g. ecs_system vs ecs_system_init) won't work since they rely on C-style initializers, but all the functions are usable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request portability Run on more platforms
Projects
None yet
Development

No branches or pull requests

3 participants