Question

How do I trace my compliation order? (So that I may re-order it)

My issue: I'm running Visual Studio 2012 writing a C++ application. I binded a scripting system, Lua, to my project using LuaBind

LuaBind hides away Lua stuff and figures out how to bind it to the Lua Language (or some magic)

I can take an object, call a function on it, and pass in a C++ object to be given to the lua script function

// ScriptComponent.h
class ScriptComponent : public Component
{
public:
    virtual void Initialize();
    virtual void Update();
protected:
    luabind::object luaDataTable;
    Entity* mOwner;

-

// ScriptComponent.cpp
void ScriptComponent::Initialize() {
    luabind::object compiledScript;
    luaL_loadfile(L, "myScript.lua");
    luabind::object compiledScript(luabind::from_stack(L, -1));
    luaDataTable = compiledScript();
    lua_pop(L, 1);
}

void ScriptComponent::Update() {
    luaDataTable["run"](mOwner); // Compiler breaks here.
    // Note: if I remove mOwner from the mix (and in the script file) everything works and runs fine.
}

Cool! But to get this to work, luabind needs to know what mOwner (Entity*) is and have ti defined. So, I define it in a different file:

// GameScriptingSystem.cpp
using namespace luabind;
module(inLuaState)
    [
        class_<GameObject>("GameObject"),
        class_<Entity, bases<GameObject> >("Entity")
            .def("DebugGetName", &Entity::DebugGetName)
    ];

The flow looks something like this: enter image description here

The result:

error C2504: 'Entity' : base class undefined

Full error as requested:

...
2>  Component.cpp
2>  ScriptComponent.cpp
2>boost/type_traits/is_polymorphic.hpp(46): error C2504: 'Entity' : base class undefined
2>          boost/type_traits/is_polymorphic.hpp(62) : see reference to class template instantiation 'boost::detail::is_polymorphic_imp1<T>::d2' being compiled
2>          with
2>          [
2>              T=Entity
2>          ]
2>          boost/type_traits/is_polymorphic.hpp(97) : see reference to class template instantiation 'boost::detail::is_polymorphic_imp1<T>' being compiled
2>          with
2>          [
2>              T=Entity
2>          ]
2>          boost/type_traits/is_polymorphic.hpp(102) : see reference to class template instantiation 'boost::detail::is_polymorphic_imp<T>' being compiled
2>          with
2>          [
2>              T=Entity
2>          ]
2>          luabind/detail/make_instance.hpp(42) : see reference to class template instantiation 'boost::is_polymorphic<T>' being compiled
2>          with
2>          [
2>              T=Entity
2>          ]
2>          luabind/detail/make_instance.hpp(74) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> luabind::detail::get_dynamic_class<T>(lua_State *,T *)' being compiled
2>          with
2>          [
2>              _Ty1=luabind::detail::class_id,
2>              _Ty2=void *,
2>              T=Entity
2>          ]
2>          luabind/detail/policy.hpp(228) : see reference to function template instantiation 'void luabind::detail::make_instance<T*>(lua_State *,P)' being compiled
2>          with
2>          [
2>              T=Entity,
2>              P=Entity *
2>          ]
2>          luabind/detail/convert_to_lua.hpp(87) : see reference to function template instantiation 'void luabind::detail::pointer_converter::apply<Entity>(lua_State *,T *)' being compiled
2>          with
2>          [
2>              T=Entity
2>          ]
2>          luabind/object.hpp(1072) : see reference to function template instantiation 'void luabind::detail::convert_to_lua_p<1,Entity*,Policies>(lua_State *,const T &,const Policies &)' being compiled
2>          with
2>          [
2>              Policies=luabind::detail::null_type,
2>              T=Entity *
2>          ]
2>          luabind/object.hpp(1140) : see reference to function template instantiation 'void luabind::detail::push_args_from_tuple<Index>::apply<T0,boost::tuples::detail::map_tuple_to_cons<boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>::type,luabind::detail::null_type>(lua_State *,const boost::tuples::cons<HT,TT> &,const Policies &)' being compiled
2>          with
2>          [
2>              Index=1,
2>              T0=Entity *const *,
2>              HT=Entity *const *,
2>              TT=boost::tuples::detail::map_tuple_to_cons<boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>::type,
2>              Policies=luabind::detail::null_type
2>          ]
2>          luabind/object.hpp(1140) : see reference to function template instantiation 'void luabind::detail::push_args_from_tuple<Index>::apply<T0,boost::tuples::detail::map_tuple_to_cons<boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>::type,luabind::detail::null_type>(lua_State *,const boost::tuples::cons<HT,TT> &,const Policies &)' being compiled
2>          with
2>          [
2>              Index=1,
2>              T0=Entity *const *,
2>              HT=Entity *const *,
2>              TT=boost::tuples::detail::map_tuple_to_cons<boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>::type,
2>              Policies=luabind::detail::null_type
2>          ]
2>          luabind/object.hpp(1112) : see reference to function template instantiation 'luabind::adl::object luabind::adl::call_proxy<ValueWrapper,Arguments>::call<luabind::detail::null_type>(Policies *)' being compiled
2>          with
2>          [
2>              ValueWrapper=luabind::adl::index_proxy<luabind::adl::object>,
2>              Arguments=boost::tuples::tuple<Entity *const *,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>,
2>              Policies=luabind::detail::null_type
2>          ]
2>          luabind/object.hpp(1112) : see reference to function template instantiation 'luabind::adl::object luabind::adl::call_proxy<ValueWrapper,Arguments>::call<luabind::detail::null_type>(Policies *)' being compiled
2>          with
2>          [
2>              ValueWrapper=luabind::adl::index_proxy<luabind::adl::object>,
2>              Arguments=boost::tuples::tuple<Entity *const *,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>,
2>              Policies=luabind::detail::null_type
2>          ]
2>          luabind/object.hpp(1110) : while compiling class template member function 'luabind::adl::call_proxy<ValueWrapper,Arguments>::~call_proxy(void)'
2>          with
2>          [
2>              ValueWrapper=luabind::adl::index_proxy<luabind::adl::object>,
2>              Arguments=boost::tuples::tuple<Entity *const *,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>
2>          ]
2>          ..\src\Game\GameObjects\Components\ScriptComponent.cpp(75) : see reference to function template instantiation 'luabind::adl::call_proxy<ValueWrapper,Arguments>::~call_proxy(void)' being compiled
2>          with
2>          [
2>              ValueWrapper=luabind::adl::index_proxy<luabind::adl::object>,
2>              Arguments=boost::tuples::tuple<Entity *const *,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>
2>          ]
2>          ..\src\Game\GameObjects\Components\ScriptComponent.cpp(75) : see reference to class template instantiation 'luabind::adl::call_proxy<ValueWrapper,Arguments>' being compiled
2>          with
2>          [
2>              ValueWrapper=luabind::adl::index_proxy<luabind::adl::object>,
2>              Arguments=boost::tuples::tuple<Entity *const *,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>
2>          ]
2>boost/type_traits/is_polymorphic.hpp(34): error C2504: 'Entity' : base class undefined
2>          boost/type_traits/is_polymorphic.hpp(62) : see reference to class template instantiation 'boost::detail::is_polymorphic_imp1<T>::d1' being compiled
2>          with
2>          [
2>              T=Entity
2>          ]
2>  Map.cpp
2>  Generating Code...
2>  Compiling...
2>  GameScriptingSystem.cpp
2>  PoCToolsInterface.cpp
..

As far as I can tell, its due to the build order. My best guess is that Luabind does all this stuff at compiletime, and when I look at the compilation first, ScriptComponent is compiled first, GameScriptSystem is compiled after. When ScriptComponent builds, alll the luabind errors through. THEN after GameScriptSystem builds (which defines all the stuff LuaBind is complaining about)

So:

  • How do I track my build order? See what files are triggering build of others, so that I may re-arrange it to my liking? (its a big project, its not as easy as looking at it for 2 seconds)

  • If you know luabind, am I right about this being the issue?

Other data:

-- myScript.lua
local Cat = {}
local ticks = 0

function Cat.run(entity)
    ticks = ticks + 1
    LOG(tostring(ticks))
    LOG(entity:DebugGetName())
end

return Cat
Was it helpful?

Solution

No, it's not due to build order. C++ compilation units build independently. Even if the .cpp file which defines your entity has already been compiled, it won't be available automatically.

C++ never goes searching for definitions of entities. The only way to use an entity inside a compilation unit is for a declaration (depending on the usage, you might need only a forward declaration or a full definition) for that entity to exist in that compilation unit. Usually header files and #include are used to avoid code duplication.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top