Using GCC/Sublime to compile SDL programs on Linux - c++

How can I use either GCC or the Sublime IDE to compile my SDL based project on Linux?
gcc main.cpp -o main -lSDL2
I have tried this and I just get errors that seem to be pointing to the idea that either the program isn't pointing at the library the right way or the compiler isn't recognizing the library. On Sublime I have essentially done the same thing by creating my own build system for SDL, but it doesn't really seem to do anything at all. What might I be doing wrong?
{
"cmd" : [ "gcc", "$file", "-o", "-lSDL2" ]
{
I hope this question is appropriate on this stack, it can be considered Linux tooling but the Linux and Unix stack doesn't suggest programming questions unless they consist of shell scripting.
Here is just the basic Hello World that I am testing (Obviously not quite formatted correctly, but you get the idea.) :
#include <SDL2/SDL.h>
int main(int argc, char *argv[]) {
int win = 1;
SDL_Event event;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_WM_SetCaption("Window", NULL);
SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE);
while (win) {
SDL_WaitEvent(&event);
if (event.type == SDL_QUIT)
win = 0;
}
SDL_Quit();
return 0;
}
When the program is compiled I use the GCC command posted at the top and get these errors:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:19:37: error: ‘SDL_WM_SetCaption’ was not declared in this scope
SDL_WM_SetCaption("Window", NULL);
^
main.cpp:20:36: error: ‘SDL_HWSURFACE’ was not declared in this scope
SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE);
^
main.cpp:20:49: error: ‘SDL_SetVideoMode’ was not declared in this scope
SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE);
^
I have also tried pointing directly to header files in GCC with:
gcc main.cpp -o main -l/usr/include/SDL2
I did check to make sure that the header files were in usr/include/SDL2, maybe the actual library isn't installed in the right place for development?

The errors from GCC were cause by calling functions in SDL2 that didn't exist. Changing the previous SDL Video calls to:
SDL_CreateWindow(
"Window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
SDL_WINDOW_OPENGL
);
was the right way to create a window in SDL 2;
Following with the GCC commands:
gcc main.cpp -o main -lSDL2
Compiled the code correctly and thus made it executable. Thank you for pointing that out #HolyBlackCat

Related

GTK C++: Could not find signal handler Did you compile with -rdynamic?

I am new at GTK programming and I am facing the following issue. I can compile the code without any warnings or errors however when I execute the binary I get this massage and the button does not work.
The error looks like this:
(project:9686): Gtk-WARNING **: 16:26:31.359: Could not find signal handler 'on_button_clicked'. Did you compile with -rdynamic?
That is the code:
#include <gtk/gtk.h>
static const gchar *interface =
"<interface>"
" <object class=\"GtkWindow\" id=\"main-window\">"
" <signal name=\"destroy\" handler=\"gtk_main_quit\"/>"
" <child>"
" <object class=\"GtkButton\" id=\"my-button\">"
" <property name=\"label\">Hallo, Welt!</property>"
" <signal name=\"clicked\" handler=\"on_button_clicked\"/>"
" </object>"
" </child>"
" </object>"
"</interface>";
G_MODULE_EXPORT void on_button_clicked (GtkWidget *w, gpointer d)
{
g_print ("Hallo, Welt!\n");
}
int main (int argc, char *argv[])
{
GtkBuilder *builder;
GError *error = NULL;
GtkWidget *window;
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, interface, -1, &error);
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET(gtk_builder_get_object (builder, "main-window"));
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
I am working at a Linux machine and I compiled in the terminal with the following command:
g++ -Wall -std=c++0x project.cpp `pkg-config --cflags --libs gtk+-3.0 gmodule-2.0` -o project
I tried to compile with:
-rdynamic
-Wl,--export-dynamic
-lgmodule-2.0
pkg-config --cflags --libs gtk+-3.0 gmodule-no-export-2.0
but nothing worked.
It's hard to know for sure, but I would guess the problem is that you are compiling using a C++ compiler whereas your example is written in C. The C++ compiler is "mangling" the names of your exported symbols. If you aren't writing the rest of your program in C++, then I would recommend compiling with gcc -std=c99 instead of g++ -std=c++0x.
On the other hand, if the rest of your program does need to be written in C++, then you will need to prefix every symbol that you want to export for GtkBuilder (which does not know about C++ name mangling) with extern "C", or place them all together inside one or more extern "C" { ... } blocks. This will prevent the name from being mangled, so then GtkBuilder will be able to find it.
To check whether this is the case, try running nm -g | grep on_button_clicked (without any "demangle" option) on your compiled file. If the name is mangled, you will see something like __Z17on_button_clicked13BLAH14BLAH whereas if it is not, then you will just see _on_button_clicked.

Problems compiling C++ programs with wineg++/winelib

I am having trouble compiling C++ programs with wineg++. To illustrate my problem, I have written two test programs.
msgbox.cpp
#include <algorithm>
#include <iterator>
#include <cstdio>
#include <windows.h>
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
char buf[30], *pos = buf;
int xs[] = {1,3,2,4,3,5,4,6,5,7,6,8,7,9};
std::sort( std::begin(xs), std::end(xs) );
for (int x : xs) {
pos += std::sprintf(pos, "%d ", x);
}
MessageBox(0, buf, "Hello", 0);
return 0;
}
frame.cpp
#include "../win32xx/include/wxx_wincore.h"
#include "../win32xx/include/wxx_frame.h"
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
CWinApp winApp;
CFrame frame;
CWnd view;
frame.SetView(view);
frame.Create();
winApp.Run();
}
The second program uses the Win32++ library, which I can't recommend enough.
Both programs compile and run just fine using a cross-compiler:
okuu% x86_64-w64-mingw32-g++ msgbox.cpp -o msgbox.exe
okuu% wine ./msgbox.exe
okuu% x86_64-w64-mingw32-g++ frame.cpp -o frame.exe -lgdi32 -lcomctl32 -static
okuu% wine ./frame.exe
okuu% rm *exe*
But I want to use winelib so that I can use both the Windows API and Unix libraries. This is what I tried first:
okuu% wineg++ msgbox.cpp -o msgbox.exe
okuu% ./msgbox.exe
okuu% wineg++ frame.cpp -o frame.exe -mwindows
In file included from ../win32xx/include/wxx_appcore.h:57:0,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:1:
../win32xx/include/wxx_appcore0.h:120:12: fatal error: process.h: No such file or directory
#include <process.h>
^~~~~~~~~~~
compilation terminated.
winegcc: g++ failed
Then I read wineg++'s man page, which says:
-mno-cygwin
Use Wine implementation of MSVCRT, instead of linking against the host system libc. This is necessary for the vast majority of Win32 applications, as they typically depend on various features of MSVCRT. This switch is also used by the MinGW compiler to link against MSVCRT on Windows, instead of linking against Cygwin libc. Sharing the syntax with MinGW makes it very easy to write Makefiles that work under Wine, MinGW+MSYS, or MinGW+Cygwin.
So I tried again with -mno-cygwin, and got a 2000-line error message that begins with:
okuu% wineg++ frame.cpp -o frame.exe -mwindows -mno-cygwin
In file included from /usr/include/c++/7.2.1/cstdlib:75:0,
from /usr/include/c++/7.2.1/bits/stl_algo.h:59,
from /usr/include/c++/7.2.1/algorithm:62,
from ../win32xx/include/wxx_appcore0.h:110,
from ../win32xx/include/wxx_appcore.h:57,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:1:
/usr/include/stdlib.h:310:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *fptr; /* Front pointer. */
^~~~~~~
wint_t
/usr/include/stdlib.h:311:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *rptr; /* Rear pointer. */
^~~~~~~
wint_t
/usr/include/stdlib.h:312:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *state; /* Array of state values. */
^~~~~~~
wint_t
/usr/include/stdlib.h:316:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *end_ptr; /* Pointer behind state table. */
^~~~~~~
wint_t
/usr/include/stdlib.h:320:8: error: ‘int32_t’ has not been declared
int32_t *__restrict __result) __THROW __nonnull ((1, 2));
^~~~~~~
So it seems C99's fixed-size integer types are not available. That seems easy enough to solve:
frame.cpp
#include <stdint.h>
#include "../win32xx/include/wxx_wincore.h"
#include "../win32xx/include/wxx_frame.h"
// etc. etc. etc.
And I tried again, but got a different 2000-line error message that begins with:
okuu% wineg++ frame.cpp -o frame.exe -mwindows -mno-cygwin
In file included from /usr/include/c++/7.2.1/cwchar:44:0,
from /usr/include/c++/7.2.1/bits/postypes.h:40,
from /usr/include/c++/7.2.1/bits/char_traits.h:40,
from /usr/include/c++/7.2.1/string:40,
from ../win32xx/include/wxx_appcore0.h:111,
from ../win32xx/include/wxx_appcore.h:57,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:2:
/usr/local/include/wine/msvcrt/wchar.h:398:23: error: conflicting declaration of C function ‘size_t mbstowcs(wchar_t*, const char*, size_t)’
size_t __cdecl mbstowcs(wchar_t*,const char*,size_t);
^~~~~~~~
At this point I have run out of ideas. This is what I have understood so far:
My system's libc and Wine's MSVCRT have conflicting definitions. (This was probably to be expected.)
My system's libc++ is hardwired to work with my system's libc.
Wine comes with a MSVCRT, but not with a C++ standard library implementation.
The logical course of action with the information I have so far would be to look for a C++ standard library implementation that's compatible with Wine's MSVCRT, but I don't know of one. Does anybody here know of one?
The only solution I can think of is to stick with the system libc and write your own process.h. This file should either #include the standard header files that have the functions Win32++ needs or provide its own implementations of those functions. If Win32++ won't compile without a particular function but your program does not actually depend on that function, the implementation of that function can simply return 0 or another fake value.
If the system libc has a header file that Win32++ asks for, but the file does not declare all of the functions that Win32++ expects, you'll have to write a header file such as win32xx-compat.h that defines those functions and #include it before any Win32++ header.

How to cross-compile with SDL 2 from Linux for Windows

I tried to compile a simple C++ program that uses SDL 2 with the mingw-w64-g++ compiler on my Arch Linux (64bits).
For this I downloaded SDL2-devel-2.0.4-mingw.tar.gz from here
prog.cpp:
#include <SDL.h>
int main ()
{
SDL_Init (SDL_INIT_VIDEO);
SDL_Window *sdlWnd = SDL_CreateWindow ("Test", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 800, 600, 0);
SDL_Event event;
bool running = true;
while (running) {
while (SDL_PollEvent (&event)) {
if (event.type == SDL_QUIT) {
running = false;
break;
}
}
}
return 0;
}
Makefile:
GPP = x86_64-w64-mingw32-g++
prog.exe: prog.o
$(GPP) -o prog.exe prog.o -LSDL2-2.0.4/lib/x64 -lSDL2main -lSDL2
prog.o: prog.cpp
$(GPP) -o prog.o -c -ISDL2-2.0.4/include prog.cpp
Now making gives the error:
x86_64-w64-mingw32-g++ -o prog.exe prog.o -LSDL2-2.0.4/lib/x64 -lSDL2main -lSDL2
Warning: corrupt .drectve at end of def file
SDL2-2.0.4/lib/x64/SDL2main.lib(./x64/Release/SDL_windows_main.obj):(.text[main]+0x1c): undefined reference to `SDL_main'
Why undefined reference to `SDL_main' ? Although I specified -lSDL2main ?
What did I do wrong? :(
Okay, it was because of the main functions signature, that has to be declared as:
int main(int argc, char *argv[])
according to the official SDL FAQ:
Make sure that you are declaring main() as:
#include "SDL.h"
int main(int argc, char *argv[])
You should be using main() instead of WinMain() even though you are
creating a Windows application, because SDL provides a version of
WinMain() which performs some SDL initialization before calling your
main code. If for some reason you need to use WinMain(), take a look
at the SDL source code in src/main/win32/SDL_main.c to see what kind
of initialization you need to do in your WinMain() function so that
SDL works properly.

libtorque - how do i include the PBSD_status function?

I am writing an application to test whether pbs_connect() is working or not. Here is my code:
#include <stdio.h>
#include "/usr/include/torque/pbs_ifl.h"
#include "/usr/include/torque/pbs_error.h"
#include <pbs_config.h>
#include "libpbs.h"
int main() {
printf("Hello world\n");
int server = pbs_connect("inferno.local");
//batch_status * stat1 = pbs_statserver(server, NULL, NULL);
pbs_errno = 0;
batch_status * stat1 = PBSD_status(server, 21, (char *)"", NULL, NULL);
printf("fd: %d\n", server);
//printf("text: %s\n", stat1->text);
//printf("name: %s\n", stat1->name);
printf("name: %d\n", pbs_errno);
return 0;
}
//compiled using - //g++ -o test test.c -L/usr/lib64 -ltorque
I get:
# g++ -o test test.c -L/usr/lib64 -ltorque
test.c:7:24: error: pbs_config.h: No such file or directory
test.c:8:20: error: libpbs.h: No such file or directory
test.c: In function 'int main()':
test.c:19: warning: deprecated conversion from string constant to 'char*'
test.c:24: error: 'PBSD_status' was not declared in this scope
The source file that contains PBSD_status can be found here:
https://github.com/adaptivecomputing/torque/blob/4.2.7/src/lib/Libifl/PBSD_status.c
Is there something i need to include in my g++ command to get this to work? I have checked in /usr/lib64/, and there is no libpbs.h or pbs_config.h. Where would they be, if they aren't there?
As far as your headers, you're running into the difference between installed and not installed headers. Essentially, a software project doesn't install every header inside that project, only relevant ones for the API. These other two aren't in the API and therefore aren't installed. You need to reference their path.
As far as including PBSD_status() in the library, you could edit the Makefile for Libpbs to include the source file for PBSD_status() and then rebuild, or you could link to the libifl library, which is in src/lib/Libifl from the base directory for the project.

OpenGL Loader Generator undefined reference to gl::BindBuffer, etc (OpenGL Functions)

I have a problem when using OpenGL Loader Generator, which when I try to compile my code, it doesn't work. It throws an error saying undefined reference to any opengl function I use, such as gl::BindBuffer, gl::GenBuffers, etc. I'm using pointer_cpp/func_cpp style.
My simple code that I'm using is
#include "gl_core_3_3.hpp"
#include <GL/glfw.h>
int main(int argc, char *argv[]) {
glfwInit();
glfwOpenWindow(1024, 768, 0, 0, 0, 0, 0, 0, GLFW_WINDOW);
gl::exts::LoadTest didLoad = gl::sys::LoadFunctions();
if(!didLoad) {
glfwTerminate();
return 1;
}
return 0;
}
When I compile that, it says undefined reference to gl::sys::LoadFunctions too. The command I'm using to compile is
g++ main.cpp -lglfw -lGL -lGLU
I'm on Arch Linux and using Vim with clang as my IDE.
g++ main.cpp -lglfw -lGL -lGLU
I don't see where you're including the generated source file. It's not a header-only loading system. It doesn't generate a library, but it does generate source code, which must be compiled.