- Изменено
Need help using spine-sfml with spine-cpp and cmake
Hello there.
I am currently evaluating spine to be a core part of one of my projects and having a little trouble getting it to work properly.
I am using SFML 2.4.2 (intentional. I will upgrade to 2.5 later on.)
Here is the error:
[ 3%] Built target spine-sfml
[ 96%] Built target spine-cpp
[ 98%] Linking CXX executable DemoRPG
Undefined symbols for architecture x86_64:
"sf::CircleShape::CircleShape(float, unsigned long)", referenced from:
_main in main.cpp.o
"sf::VertexArray::clear()", referenced from:
spine::SkeletonDrawable::draw(sf::RenderTarget&, sf::RenderStates) const in libspine-sfml.a(spine-sfml.cpp.o)
"sf::VertexArray::append(sf::Vertex const&)", referenced from:
spine::SkeletonDrawable::draw(sf::RenderTarget&, sf::RenderStates) const in libspine-sfml.a(spine-sfml.cpp.o)
"sf::VertexArray::VertexArray(sf::PrimitiveType, unsigned long)", referenced from:
spine::SkeletonDrawable::SkeletonDrawable(spine::SkeletonData*, spine::AnimationStateData*) in libspine-sfml.a(spine-sfml.cpp.o)
"sf::RenderStates::Default", referenced from:
_main in main.cpp.o
"sf::RenderTarget::draw(sf::Drawable const&, sf::RenderStates const&)", referenced from:
_main in main.cpp.o
spine::SkeletonDrawable::draw(sf::RenderTarget&, sf::RenderStates) const in libspine-sfml.a(spine-sfml.cpp.o)
"sf::RenderTarget::clear(sf::Color const&)", referenced from:
_main in main.cpp.o
"sf::RenderWindow::RenderWindow(sf::VideoMode, sf::String const&, unsigned int, sf::ContextSettings const&)", referenced from:
_main in main.cpp.o
"sf::RenderWindow::~RenderWindow()", referenced from:
_main in main.cpp.o
"sf::Color::Green", referenced from:
_main in main.cpp.o
"sf::Color::Color(unsigned char, unsigned char, unsigned char, unsigned char)", referenced from:
_main in main.cpp.o
"sf::Shape::setFillColor(sf::Color const&)", referenced from:
_main in main.cpp.o
"sf::Shape::~Shape()", referenced from:
sf::CircleShape::~CircleShape() in main.cpp.o
"sf::String::String(char const*, std::__1::locale const&)", referenced from:
_main in main.cpp.o
"sf::Vertex::Vertex()", referenced from:
spine::SkeletonDrawable::draw(sf::RenderTarget&, sf::RenderStates) const in libspine-sfml.a(spine-sfml.cpp.o)
"sf::Window::close()", referenced from:
_main in main.cpp.o
"sf::Window::display()", referenced from:
_main in main.cpp.o
"sf::Window::pollEvent(sf::Event&)", referenced from:
_main in main.cpp.o
"sf::Texture::setRepeated(bool)", referenced from:
spine::SFMLTextureLoader::load(spine::AtlasPage&, spine::String const&) in libspine-sfml.a(spine-sfml.cpp.o)
"sf::Texture::loadFromFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, sf::Rect<int> const&)", referenced from:
spine::SFMLTextureLoader::load(spine::AtlasPage&, spine::String const&) in libspine-sfml.a(spine-sfml.cpp.o)
"sf::Texture::setSmooth(bool)", referenced from:
spine::SFMLTextureLoader::load(spine::AtlasPage&, spine::String const&) in libspine-sfml.a(spine-sfml.cpp.o)
"sf::Texture::Texture()", referenced from:
spine::SFMLTextureLoader::load(spine::AtlasPage&, spine::String const&) in libspine-sfml.a(spine-sfml.cpp.o)
"sf::Texture::~Texture()", referenced from:
spine::SFMLTextureLoader::unload(void*) in libspine-sfml.a(spine-sfml.cpp.o)
"sf::BlendMode::BlendMode(sf::BlendMode::Factor, sf::BlendMode::Factor, sf::BlendMode::Equation)", referenced from:
___cxx_global_var_init in libspine-sfml.a(spine-sfml.cpp.o)
___cxx_global_var_init.1 in libspine-sfml.a(spine-sfml.cpp.o)
___cxx_global_var_init.2 in libspine-sfml.a(spine-sfml.cpp.o)
___cxx_global_var_init.3 in libspine-sfml.a(spine-sfml.cpp.o)
___cxx_global_var_init.4 in libspine-sfml.a(spine-sfml.cpp.o)
___cxx_global_var_init.5 in libspine-sfml.a(spine-sfml.cpp.o)
___cxx_global_var_init.6 in libspine-sfml.a(spine-sfml.cpp.o)
...
"sf::BlendMode::BlendMode()", referenced from:
spine::SkeletonDrawable::draw(sf::RenderTarget&, sf::RenderStates) const in libspine-sfml.a(spine-sfml.cpp.o)
"sf::VideoMode::VideoMode(unsigned int, unsigned int, unsigned int)", referenced from:
_main in main.cpp.o
"sf::operator!=(sf::BlendMode const&, sf::BlendMode const&)", referenced from:
spine::SkeletonDrawable::draw(sf::RenderTarget&, sf::RenderStates) const in libspine-sfml.a(spine-sfml.cpp.o)
"sf::Window::isOpen() const", referenced from:
_main in main.cpp.o
"sf::Texture::getSize() const", referenced from:
spine::SkeletonDrawable::draw(sf::RenderTarget&, sf::RenderStates) const in libspine-sfml.a(spine-sfml.cpp.o)
spine::SFMLTextureLoader::load(spine::AtlasPage&, spine::String const&) in libspine-sfml.a(spine-sfml.cpp.o)
"typeinfo for spine::SpineObject", referenced from:
typeinfo for spine::String in main.cpp.o
typeinfo for spine::SkeletonClipping in libspine-sfml.a(spine-sfml.cpp.o)
typeinfo for spine::Color in libspine-sfml.a(spine-sfml.cpp.o)
typeinfo for spine::Vector<float> in libspine-sfml.a(spine-sfml.cpp.o)
typeinfo for spine::Vector<spine::Color> in libspine-sfml.a(spine-sfml.cpp.o)
typeinfo for spine::Vector<unsigned short> in libspine-sfml.a(spine-sfml.cpp.o)
"typeinfo for spine::TextureLoader", referenced from:
typeinfo for spine::SFMLTextureLoader in libspine-sfml.a(spine-sfml.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [DemoRPG] Error 1
make[2]: *** [CMakeFiles/DemoRPG.dir/all] Error 2
make[1]: *** [CMakeFiles/DemoRPG.dir/rule] Error 2
make: *** [DemoRPG] Error 2
Here is my folder structure: (In attachments)
And here is my CMakeList.txt:
cmake_minimum_required(VERSION 3.13)
project(DemoRPG)
# includes the FindXXX.cmake files
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
set(CMAKE_CXX_STANDARD 17)
# OpenGL
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
# SFML
find_package(SFML 2 REQUIRED audio graphics window system)
include_directories(${SFML_INCLUDE_DIR})
# SFML +2.5. Remove findSFML.cmake after upgrading
#find_package(SFML 2.5 COMPONENTS graphics audio REQUIRED)
# Spine + Spine-SFML
set(SPINE_DIR vendor/spine-cpp/spine-cpp/)
set(SPINE_SFML_DIR vendor/spine-sfml/cpp)
add_subdirectory(vendor/spine-cpp)
add_subdirectory(vendor/spine-sfml/cpp)
include_directories(${SPINE_SFML_DIR}/src/)
include_directories(${SPINE_SFML_DIR}/include/)
include_directories(${SPINE_DIR}/src)
include_directories(${SPINE_DIR}/include)
file(GLOB SPINE_SFML_INCLUDES "${SPINE_SFML_DIR}/src/spine/*.h")
file(GLOB SPINE_SFML_SOURCES "${SPINE_SFML_DIR}/src/spine/*.cpp")
add_library(spine-sfml STATIC ${SPINE_SFML_INCLUDES} ${SPINE_SFML_SOURCES})
set(CMAKE_INCLUDE_PATH ${INCLUDE_DIR}:${SPINE_SFML_INCLUDES}:${SPINE_DIR}/include)
#add_library(spine STATIC ${SPINE_SFML_INCLUDES} ${SPINE_SFML_SOURCES})
add_executable(
DemoRPG
main.cpp
)
target_link_libraries(DemoRPG spine-cpp spine-sfml ${OPENGL_LIBRARIES})
I can also provide a MVP if it helps.
The linker errors mean that you aren't actually linking the SFML library with your executable. I can't see anything immediately wrong with your CMakeList.txt file, but I assume this somehow fails:
find_package(SFML 2 REQUIRED audio graphics window system)
Thank you for your reply.
When I directly link the sfml files like this:
target_link_libraries(DemoRPG spine-cpp ${SFML_LIBRARIES} ${SFML_DEPENDENCIES} ${OPENGL_LIBRARIES})
Then I get this:
[ 96%] Built target spine-cpp
Scanning dependencies of target DemoRPG
[ 98%] Linking CXX executable DemoRPG
Undefined symbols for architecture x86_64:
"spine::getDefaultExtension()", referenced from:
spine::SpineExtension::getInstance() in libspine-cpp.a(Extension.cpp.o)
"typeinfo for spine::SpineObject", referenced from:
typeinfo for spine::String in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [DemoRPG] Error 1
make[2]: *** [CMakeFiles/DemoRPG.dir/all] Error 2
make[1]: *** [CMakeFiles/DemoRPG.dir/rule] Error 2
make: *** [DemoRPG] Error 2
Maybe this helps.
I would suggest to base your CMake build on our SFML example project build. CMake is a beast, and it's hard to debug a build without having everything locally to play around with (for which I'm afraid I currently don't have the time). spine-runtimes/CMakeLists.txt at 3.7
Alternatively, you can just take the .cpp and .h files from the spine-cpp and spine-sfml/cpp runtime and plunge them into your project without trying to have all of them build as separate modules. Our C++ code does not require any special build flags or modifications to the build options of your main project.
I finally got it to work...
add_executable(
DemoRPG
main.cpp
${SPINE_SFML_INCLUDES}
${SPINE_SFML_SOURCES}
${SPINE_CPP_INCLUDES}
${SPINE_CPP_SOURCES}
)
Adding everything to the executable.
The problem now is, rendering the assets.
I get this error when using the same assets from the example application: spineboy-pro.json and spineboy-pma.atlas
0 start: walk
0 event: walk, footstep: 0, 0.000000, (null) 1.000000 0.000000Process finished with exit code 11
Looks like your app crashed. I also see you are uaing CLion. The best way to figure out what's going on is to the app in debug mode. The debugger will stop in the part of the code that's crashing. Please post the full stack trace, as well as your code for rendering.
It does look like, the texture variable in the sfml runtime is still null.
This indicates that loading the texture atlas of your skeleton didn't succeed. Can you show me the code that loads the atlas, skeleton json/binary file, and instantiation of the spine::Skeleton
?
If you need anything else, just tell me.
There you go:
You'll need to pass an SFMLTextureLoader
to the Atlas constructor. See our SFML example: spine-runtimes/main.cpp at 3.7
Wow. Thanks. It finally runs!