#include<iostream>
#include <SDL_mixer.h>
#include <SDL.h>
using namespace std;
int main(int argc, char* argv[])
{
SDL_Init(SDL_INIT_AUDIO);
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
{
cout << "Error: " << Mix_GetError() << std::endl;
}
Mix_Music* song = Mix_LoadMUS("sample.wav");
Mix_PlayMusic(song, 1);
Mix_FreeMusic(song);
song = nullptr;
Mix_Quit();
SDL_Quit();
return 0;
}
I am trying to play a simple song, that I converted to WAV. It is located within the program's folder. I didn't get any errors/warnings when compling and the libraries seem to be linked correctly. On failure, loadMUS returns NULL (which isn't the case) and PlayMusic returns -1 upon failure (which again isn't the case). Yet, when I run the program nothing is heard. This is my first time working with SDL.
To just play a wave file this sample will work with SDL2:
#include <SDL.h>
#include <SDL_audio.h>
int main() {
SDL_Init(SDL_INIT_AUDIO);
SDL_AudioSpec spec{};
Uint8 *audio_buf{};
Uint32 audio_len{};
SDL_LoadWAV("path_to.wav", &spec, &audio_buf, &audio_len);
SDL_AudioSpec ob_spec{};
auto device = SDL_OpenAudioDevice(NULL, 0, &spec, &ob_spec, SDL_AUDIO_ALLOW_ANY_CHANGE);
SDL_QueueAudio(device, audio_buf, audio_len);
SDL_PauseAudioDevice(device, 0);
SDL_Delay(5000);
SDL_CloseAudioDevice(device);
SDL_FreeWAV(audio_buf);
SDL_QuitSubSystem(SDL_INIT_AUDIO);
}
BTW to link easy to SDL2 just use CMake with
cmake_minimum_required(VERSION 3.19)
project(sample_sdl VERSION 1.0)
find_package(SDL2 REQUIRED)
add_executable(${PROJECT_NAME} src/main.cpp)
set_property(TARGET ${PROJECT_NAME} PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
target_link_libraries(${PROJECT_NAME} PRIVATE SDL2::SDL2 SDL2::SDL2main)
Related
I'm trying to link my C++ program with static Boost::program_options and dynamic Boost::log libraries.
Here is my CMakeList.txt file:
project(test)
add_executable(testprog "main.cpp")
add_definitions(-DBOOST_ALL_NO_LIB)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost COMPONENTS program_options)
target_link_libraries(testprog PRIVATE Boost::program_options)
set(Boost_USE_STATIC_LIBS OFF)
add_definitions(-DBOOST_LOG_DYN_LINK)
find_package(Boost COMPONENTS log)
target_link_libraries(testprog PRIVATE Boost::log)
and my main.cpp file:
#define BOOST_ALL_NO_LIB
#include <iostream>
#include <string>
#include <boost/program_options.hpp>
#include <boost/log/trivial.hpp>
int main(int argc, char* argv[])
{
namespace po = boost::program_options;
po::options_description desc("allowed arguments");
desc.add_options()("log", po::value<std::string>(), "log level");
po::variables_map options;
po::store(po::command_line_parser(argc, argv).options(desc).run(), options);
po::notify(options);
if (options.count("log")) {
std::cout << "log level: " << options["log"].as<std::string>() << std::endl;
}
BOOST_LOG_TRIVIAL(info) << "test message";
return 0;
}
I'm getting boost_filesystem.dll is missing from your computer error.
If I get rid of set(Boost_USE_STATIC_LIBS OFF) line, I'm getting unresolved external symbols boost::log.... Looks like Boost_USE_STATIC_LIBS can be set only once during the configuration time, but I just cannot find the way to tell cmake to split static/dynamic libraries...
Thanks.
Hello,
I'm trying to use SDL2 in my C++ project under Linkux but have undefined references to core functions. I included the header files and set up the CmakeLists correctly (I think), so I don't understand why he does not find the functions.
My C++ code:
#include "SDL.h"
#include "SDL_mixer.h"
#include "SDL_image.h"
#include <iostream>
using namespace std;
#define NUM_WAVEFORMS 2
const char* _waveFileNames[] = {"Kick-Drum-1.wav", "Snare-Drum-1.wav"};
Mix_Chunk* _sample[2];
// Initializes the application data
int Init(void) {
memset(_sample, 0, sizeof(Mix_Chunk*) * 2);
// Set up the audio stream
int result = Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 512);
if( result < 0 ) {
fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
exit(-1);
}
result = Mix_AllocateChannels(4);
if( result < 0 ) {
fprintf(stderr, "Unable to allocate mixing channels: %s\n", SDL_GetError());
exit(-1);
}
// Load waveforms
for( int i = 0; i < NUM_WAVEFORMS; i++ ) {
_sample[i] = Mix_LoadWAV(_waveFileNames[i]);
if( _sample[i] == NULL ) {
fprintf(stderr, "Unable to load wave file: %s\n", _waveFileNames[i]);
}
}
return true;
}
int main() {
bool retval = Init();
cout << retval << endl;
return 0;
}
My errors:
CMakeFiles/SDL_Test.dir/src/SDL_Test.cpp.o: In function `Init()':
/home/tamas/SDL_Test/src/SDL_Test.cpp:20: undefined reference to `Mix_OpenAudio'
/home/tamas/SDL_Test/src/SDL_Test.cpp:26: undefined reference to `Mix_AllocateChannels'
/home/tamas/SDL_Test/src/SDL_Test.cpp:34: undefined reference to `Mix_LoadWAV_RW'
My CMakeLists.txt:
cmake_minimum_required (VERSION 3.5)
project (SDL_Test)
set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_STANDARD_REQUIRED TRUE)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11")
set (source_dir "${PROJECT_SOURCE_DIR}/src/")
file (GLOB source_files "${source_dir}/*.cpp")
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
add_executable (SDL_Test ${source_files})
target_link_libraries(SDL_Test ${SDL2_LIBRARIES})
Thanks for the help in advance!
SDL_Mixer comes with a pkg-config file, so you can use CMake's pkg-config support:
include(FindPkgConfig)
pkg_check_modules(SDL2_Mixer REQUIRED IMPORTED_TARGET SDL2_mixer)
target_link_libraries(SDL_Test PkgConfig::SDL2_Mixer)
The IMPORTED TARGET PkgConfig::SDL2_Mixer will be preconfigured with the correct include and linker paths.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm having a problem when trying to link SDL2 and GL libraries to Clion (cmake). Despite changing the cmakelists.txt and adding the target-link-libraries() function. So the cmake file looked like this:
cmake_minimum_required(VERSION 3.9)
project(OpenGL1)
set(CMAKE_CXX_STANDARD 17)
target_link_libraries(OpenGL1 SDL2 GL)
add_executable(OpenGL1 main.cpp Display1.cpp Display1.h)
But with no luck. Clion would not link the libraries with errors such as undifined refference to functions of the libraries.
Then a friend suggested it that I would wite that into cmakelists file:
cmake_minimum_required(VERSION 3.9)
project(OpenGL1)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lGL -lSDL2 -lOpenGL")
add_executable(OpenGL1 main.cpp Display1.cpp Display1.h)
And it kinda worked... But it would not find the -lOpenGL.
Last but not least, my project will not compile with the traditional way in the terminal with g++. And it will compile fine with one .cpp file.
My project consists of 2 cpp files and a header file. Like that:
main.cpp
Display1.cpp
Display.h
And code of the files is the following:
main.cpp
#include <iostream>
#include "Display.h"
using namespace std;
int main() {
Display d1(800,600,"Hello");
while (!d1.m_isClosed()){
d1.Clear(0.0f, 0.15f, 0.3f, 1.0f);
d1.Update();
}
return 0;
}
Display1.cpp
#include "Display.h"
#include <GL/glew.h>
using namespace std;
Display::Display(int width, int height, const string title) {
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
m_window = SDL_CreateWindow(title.c_str(),SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,width,height,SDL_WINDOW_OPENGL);
m_glContext = SDL_GL_CreateContext(m_window);
GLenum status = glewInit();
if (status != GLEW_OK)
cerr << "Glew failed!" << endl;
isClosed = false;
}
Display::~Display() {
SDL_GL_DeleteContext(m_glContext);
SDL_DestroyWindow(m_window);
SDL_Quit();
}
void Display::Clear(float r, float g, float b, float a) {
glClearColor(r,g,b,a);
glClear(GL_COLOR_BUFFER_BIT);
}
bool Display::m_isClosed() {
return isClosed;
}
void Display::Update() {
SDL_GL_SwapWindow(m_window);
SDL_Event e;
while (SDL_PollEvent(&e)){
if (e.type == SDL_QUIT)
isClosed = true;
}
}
Display1.h
#ifndef OPENGL_DISPLAY_H
#define OPENGL_DISPLAY_H
#include <iostream>
#include <SDL2/SDL.h>
using namespace std;
class Display {
SDL_Window* m_window;
SDL_GLContext m_glContext;
bool isClosed;
public:
Display(int width, int height, string title);
virtual ~Display();
void Update();
bool m_isClosed();
void Clear(float r, float g, float b, float a);
};
#endif //OPENGL_DISPLAY_H
Now, i know that others have asked the same, but nothing could help me so that's why I'm asking. I'm running Ubuntu 17.10 (64-bit). Thanks in advance!
You have to fix your CMakeLists.txt:
cmake_minimum_required(VERSION 3.9)
project(OpenGL1)
set(CMAKE_CXX_STANDARD 17)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
set(SDL2_INCLUDE_DIRS /usr/include/SDL2)
set(SDL2_LIBRARIES /usr/lib/x86_64-linux-gnu/libSDL2.so)
include_directories(${OPENGL_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS})
add_executable(OpenGL1 main.cpp Display1.cpp Display1.h)
target_link_libraries(OpenGL1 ${OPENGL_LIBRARIES} ${GLEW_LIBRARIES} ${SDL2_LIBRARIES})
First find the OpenGL files with find_package(OpenGL REQUIRED). Then set the paths for SDL2. Set the include directories for your target (OpenGL1). Add your target. Link libraries to your target.
A better way to use SDL2 is to use FindSDL2.cmake and add find_package(SDL2) to your CMakeLists.txt:
cmake_minimum_required(VERSION 3.9)
project(OpenGL1)
set(CMAKE_CXX_STANDARD 17)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(SDL2 REQUIRED)
include_directories(${OPENGL_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS})
add_executable(OpenGL1 main.cpp Display1.cpp Display1.h)
target_link_libraries(OpenGL1 ${OPENGL_LIBRARIES} ${GLEW_LIBRARIES} ${SDL2_LIBRARIES})
SDL2 installs its own cmake configuration file called sdl2-config.cmake, so you don't need to download it from github.
so I've hit a dead end, I'm simplying trying to run the following:
main.cpp:
#include <iostream>
#include <allegro5/allegro.h>
int main(int argc, char **argv) {
std::cout << "Hello, World!" << std::endl;
al_init();
std::cout << "hi" << std::endl;
return 0;
}
CMakeList.txt:
cmake_minimum_required(VERSION 3.6)
project(allegro_test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
SET(ALLEGRO_ROOT C:/Users/duck-/workspace/cpp/recources/allegro/)
INCLUDE_DIRECTORIES( ${ALLEGRO_ROOT}/include )
LINK_DIRECTORIES( ${ALLEGRO_ROOT}/lib)
add_executable(allegro_test ${SOURCE_FILES})
TARGET_INCLUDE_DIRECTORIES(allegro_test PUBLIC ${ALLEGRO_ROOT})
TARGET_LINK_LIBRARIES(allegro_test allegro)
output:
"C:\Users\duck-\.CLion2016.2\system\cmake\generated\allegro test-50fbd97d\50fbd97d\Debug\allegro_test.exe"
Process finished with exit code -1073741701 (0xC000007B)
I'm using allegro-mingw-gcc6.2.0-x64-dynamic-5.2.2.zip from here and have copyied allegro-5.2.dll, cygintl-1.dll & cygintl-2.dll to
C:\Users\duck-.CLion2016.2\system\cmake\generated\allegro test-50fbd97d\50fbd97d\Debug\
where the program's executed. I've installed .NET Framework 4.6.2. Am I missing something? cheers in advance.
Since you are building the program in a Debug configuration, you'll need to include allegro-debug-5.2.dll, and not just allegro-5.2.dll.
I've been trying to create a small test application to start working with CMake and linking libraries.
The following is done:
- I installed the libmysqlcppconn5 library on Ubuntu (ie. it is now located in /usr/lib/libmysqlcppconn5.so, just the default installation)
- I created a small .cpp file with the following content
#include <stdlib.h>
#include <iostream>
#include <mysql/mysql.h>
int main(int argc, char **argv) {
MYSQL *conn_ptr;
conn_ptr = mysql_init(NULL);
if (!conn_ptr) {
std::cout << "mysql init failed\n";
exit(1);
}
conn_ptr = mysql_real_connect (conn_ptr, "localhost", "root", "pw", "db", 0, NULL, 0);
if (conn_ptr) {
std::cout << "connection success\n";
} else {
std::cout << "connection failed\n";
}
mysql_close(conn_ptr);
How should I construct my CMakeLists.txt so it will use this shared library?
How about something like:
# Find and make sure the system have the header file
find_path(MYSQL_HEADER mysql/mysql.h)
if(MYSQL_HEADER STREQUAL "MYSQL_HEADER-NOTFOUND")
message(FATAL_ERROR "Could not find the mysql/mysql.h header file")
endif()
# Find and make sure the system have the library
find_library(MYSQL_LIBMYSQLCPPCONN5 mysqlcppconn5)
if(MYSQL_LIBMYSQLCPPCONN5 STREQUAL "MYSQL_LIBMYSQLCPPCONN5-NOTFOUND")
message(FATAL_ERROR "Could not find the mysqlcppconn5 library")
endif()
# Link the library to the target
target_link_libraries(your_target ${MYSQL_LIBMYSQLCPPCONN5})