ติดตั้งและใช้งาน SFML ด้วย CLion บน Ubuntu
Cover Image : www.jetbrains.com/clion
บทความนี้เป็นบทความที่ผมทำเป็น Note ไว้เมื่อหลายอาทิตย์ก่อน ตอนที่ลองใช้งาน SFML บน Ubuntu แล้วพบปัญหา นั่งแก้ปัญหาอยู่เกือบวัน กว่าจะสามารถแก้ปัญหาเล็กๆน้อยๆได้ เลยทำการจดไว้ ก่อนอื่น ตอนที่ทดลองใช้ SFML ก็เคยเขียน C/C++ มาบ้าง แต่เป็นการเขียนบนสภาพแวดล้อมของ Windows ทั้งหมด ใช้ Visual Studio ส่วน SFML เพิ่งเคยได้จับครั้งแรก ปัญหาที่เกิดวันนี้คือตัว CLion - New C/C++ IDE from JetBrains มองไม่เห็นไฟล์ Library ที่ include เข้าไปในโปรเจ็ค รู้สึกว่าจะต้องใช้ CMake ช่วย ซึ่งผมก็เพิ่งได้รู้จักนี้แหละ เผื่อใครมีปัญหาลักษณะเดียวกัน ก็ลองอ่านดูนะครับ :D
SFML นั้นชื่อเต็มๆคือ Simple and Fast Multimedia Library เป็น Game Engine/Library ตัวหนึ่งที่เขียนด้วย C++ เป็น Multi-Platform สามารถที่จะรันและ compile ได้ทั้ง Windows, Mac OS X, Linux หรือแม้แต่บนมือถือ (iOS และ Android)
ลิงค์ด้านล่างนี้คือแหล่งอ้างอิงของผม
Install SFML on Ubuntu
หากได้อ่านจาก official tutorial จะพบว่า มี 3 วิธีในการติดตั้ง SFML บน Linux ซึ่งผมเลือกใช้วิธีติดตั้งผ่าน Ubuntu Distro ง่ายๆครับ แค่เปิด Terminal แล้วใช้คำสั่งนี้ :
sudo apt-get install libsfml-dev
เมื่อทำการติดตั้งเสร็จ ก็ลองเช็คว่าทุกอย่างติดตั้งสมบูรณ์ครบถ้วนรวมถึงที่อยู่ของ SFML ด้วย ว่าอยู่ที่ไหน ด้วยคำสั่ง :
dpkg -L libsfml-dev
ผลลัพธ์จะแสดงที่อยู่ของ SFML ดังนี้ แสดงว่าติดตั้งเสร็จละ ง่ายๆเลย :)
/.
/usr
/usr/include
/usr/include/SFML
/usr/include/SFML/System.hpp
/usr/include/SFML/OpenGL.hpp
/usr/include/SFML/Window
/usr/include/SFML/Window/Context.hpp
/usr/include/SFML/Window/Event.hpp
/usr/include/SFML/Window/ContextSettings.hpp
/usr/include/SFML/Window/Export.hpp
/usr/include/SFML/Window/WindowStyle.hpp
/usr/include/SFML/Window/GlResource.hpp
/usr/include/SFML/Window/Mouse.hpp
/usr/include/SFML/Window/Keyboard.hpp
/usr/include/SFML/Window/Joystick.hpp
/usr/include/SFML/Window/Window.hpp
/usr/include/SFML/Window/VideoMode.hpp
/usr/include/SFML/Window/WindowHandle.hpp
/usr/include/SFML/Graphics
/usr/include/SFML/Graphics/Color.hpp
/usr/include/SFML/Graphics/View.hpp
/usr/include/SFML/Graphics/ConvexShape.hpp
/usr/include/SFML/Graphics/RenderStates.hpp
/usr/include/SFML/Graphics/RenderTarget.hpp
/usr/include/SFML/Graphics/Export.hpp
/usr/include/SFML/Graphics/PrimitiveType.hpp
/usr/include/SFML/Graphics/Vertex.hpp
/usr/include/SFML/Graphics/Font.hpp
/usr/include/SFML/Graphics/CircleShape.hpp
/usr/include/SFML/Graphics/Transformable.hpp
/usr/include/SFML/Graphics/Drawable.hpp
/usr/include/SFML/Graphics/RenderWindow.hpp
/usr/include/SFML/Graphics/Image.hpp
/usr/include/SFML/Graphics/Rect.hpp
/usr/include/SFML/Graphics/Glyph.hpp
/usr/include/SFML/Graphics/RectangleShape.hpp
/usr/include/SFML/Graphics/Sprite.hpp
/usr/include/SFML/Graphics/Rect.inl
/usr/include/SFML/Graphics/Shape.hpp
/usr/include/SFML/Graphics/RenderTexture.hpp
/usr/include/SFML/Graphics/Transform.hpp
/usr/include/SFML/Graphics/Texture.hpp
/usr/include/SFML/Graphics/Text.hpp
/usr/include/SFML/Graphics/VertexArray.hpp
/usr/include/SFML/Graphics/Shader.hpp
/usr/include/SFML/Graphics/BlendMode.hpp
/usr/include/SFML/Network.hpp
/usr/include/SFML/Network
/usr/include/SFML/Network/SocketHandle.hpp
/usr/include/SFML/Network/SocketSelector.hpp
/usr/include/SFML/Network/IpAddress.hpp
/usr/include/SFML/Network/Export.hpp
/usr/include/SFML/Network/UdpSocket.hpp
/usr/include/SFML/Network/Http.hpp
/usr/include/SFML/Network/Packet.hpp
/usr/include/SFML/Network/TcpSocket.hpp
/usr/include/SFML/Network/Socket.hpp
/usr/include/SFML/Network/TcpListener.hpp
/usr/include/SFML/Network/Ftp.hpp
/usr/include/SFML/System
/usr/include/SFML/System/Mutex.hpp
/usr/include/SFML/System/Sleep.hpp
/usr/include/SFML/System/Utf.hpp
/usr/include/SFML/System/String.hpp
/usr/include/SFML/System/Clock.hpp
/usr/include/SFML/System/Thread.inl
/usr/include/SFML/System/Export.hpp
/usr/include/SFML/System/Time.hpp
/usr/include/SFML/System/ThreadLocalPtr.inl
/usr/include/SFML/System/Utf.inl
/usr/include/SFML/System/Lock.hpp
/usr/include/SFML/System/ThreadLocalPtr.hpp
/usr/include/SFML/System/ThreadLocal.hpp
/usr/include/SFML/System/InputStream.hpp
/usr/include/SFML/System/Thread.hpp
/usr/include/SFML/System/Err.hpp
/usr/include/SFML/System/Vector2.hpp
/usr/include/SFML/System/NonCopyable.hpp
/usr/include/SFML/System/Vector3.inl
/usr/include/SFML/System/Vector3.hpp
/usr/include/SFML/System/Vector2.inl
/usr/include/SFML/Audio.hpp
/usr/include/SFML/Config.hpp
/usr/include/SFML/Graphics.hpp
/usr/include/SFML/Window.hpp
/usr/include/SFML/Audio
/usr/include/SFML/Audio/Music.hpp
/usr/include/SFML/Audio/Sound.hpp
/usr/include/SFML/Audio/Export.hpp
/usr/include/SFML/Audio/SoundBufferRecorder.hpp
/usr/include/SFML/Audio/SoundSource.hpp
/usr/include/SFML/Audio/SoundRecorder.hpp
/usr/include/SFML/Audio/Listener.hpp
/usr/include/SFML/Audio/SoundStream.hpp
/usr/include/SFML/Audio/SoundBuffer.hpp
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig/sfml-graphics.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/sfml-network.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/sfml-audio.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/sfml-all.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/sfml-window.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/sfml-system.pc
/usr/share
/usr/share/doc
/usr/share/doc/libsfml-dev
/usr/share/doc/libsfml-dev/README.Debian
/usr/share/doc/libsfml-dev/copyright
/usr/lib/x86_64-linux-gnu/libsfml-system.so
/usr/lib/x86_64-linux-gnu/libsfml-window.so
/usr/lib/x86_64-linux-gnu/libsfml-graphics.so
/usr/lib/x86_64-linux-gnu/libsfml-audio.so
/usr/lib/x86_64-linux-gnu/libsfml-network.so
/usr/share/doc/libsfml-dev/changelog.Debian.gz
Download CLion
ต่อมา ดาวน์โหลด IDE ซึ่งจะใช้ CLion ใครยังไม่รู้จักก็ลองอ่านจากลิงค์ได้เลย Download CLion ทำการ Extract Folder ออกมา จะไว้ที่ไหนก็ตามสะดวกเลยครับ ่่ส่วนไฟล์ Execute ของมันจะอยู่ภายในโฟลเดอร์ /bin
ทำการเปิด CLion ด้วยคำสั่งนี้
cd path/to/clion/bin ./clion.sh
เมื่อ CLion ถูกเปิด ก็เลือก Theme, Config อะไรให้เรียบร้อย ดังภาพเลย
Then create new Project, then try to create simple SFML จากนั้น ลองสร้าง New Project ด้วย SFML (รายละเอียดและวิธีการสร้างผมไม่พูดถึงนะครับ บทความนี้จริงๆโฟกัสไปที่ปัญหา CLion มองไม่เห็นไฟล์ library ที่ include มากกว่า)
// in file main.cpp
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(shape);
window.display();
}
return 0;
}
หากว่าปกติ เวลาเราสั่งรันโปรแกรมด้วยการคลิ๊กปุ่ม Run จะพบว่ามี Error undefined reference
ของ SFML ต่างๆ เพียบเลย แต่ถ้าใช้วิธีสั่งรันผ่าน Command Line ด้วยวิธีข้างล่างนี้จะไม่มีปัญหาอะไร
g++ main.o -o sfml-app -lsfml-graphics -lsfml-window -lsfml-system ./sfml-app
ผลลัพธ์ปกติดี
แต่ปัญหาของผมคือ ทำไมต้องสั่งผ่าน Command Line ด้วยละ ในเมื่อคลิก Run ทีเดียว ก็ให้มันรันไม่ได้หรอ ก็เลยไปหาวิธี ว่าทำไม CLion มองไม่เห็น Library ของ SFML นะ จนได้คำตอบ
Build SFML with CMAKE
ต้องใช้ CMAKE ครับ ถึงแม้ว่าจะรันได้ปกติผ่าน Terminal แต่มันก็ลำบากกว่าการกดปุ่มนะ หาคำตอบจนได้ไปเจออันนี้เข้า Build your SFML Project with CMAKE get เลย
- ทำการสร้างโฟลเดอร์
cmake_modules
และก็ดาวน์โหลดไฟล์จากที่นี่ FindSFML.cmake มาใส่ - แก้ไขไฟล์
CMakeLists.txt
โดยการเพิ่มโค๊ดข้างล่างนี้ลงไป
# Define sources and executable
set(EXECUTABLE_NAME "SFML")
add_executable(${EXECUTABLE_NAME} main.cpp)
# Detect and add SFML
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
find_package(SFML 2 REQUIRED system window graphics network audio)
if(SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES})
endif()
สุดท้ายไฟล์ CMakeLists.txt
ก็จะมีหน้าตาแบบนี้
cmake_minimum_required(VERSION 2.8.4)
project(SimpleSFML)
set(SOURCE_FILES main.cpp)
add_executable(SimpleSFML ${SOURCE_FILES})
# Define sources and executable
set(EXECUTABLE_NAME "SFML")
add_executable(${EXECUTABLE_NAME} main.cpp)
# Detect and add SFML
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
find_package(SFML 2 REQUIRED system window graphics network audio)
if(SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES})
endif()
และ File Structure จะได้แบบนี้
├── CMakeLists.txt
├── cmake_modules
│ └── FindSFML.cmake
└── main.cpp
กดปุ่ม Reload Change และก็เลือก Executeable Name ชื่อ SFML และก็ Run ได้ปกติ
Fin! :D
- Authors
- Name
- Chai Phonbopit
- Website
- @Phonbopit