I'm making a program that uses OpenGL and SDL2 in C and wanted to use Cimgui as my gui library however, when trying to include the correct backends I'm getting these linker errors:
main.c:104:5: warning: implicit declaration of function 'ImGui_ImplSDL2_InitForOpenGL' [-Wimplicit-function-declaration]
104 | ImGui_ImplSDL2_InitForOpenGL(window, context);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:105:5: warning: implicit declaration of function 'ImGui_ImplOpenGL3_Init' [-Wimplicit-function-declaration]
105 | ImGui_ImplOpenGL3_Init(glsl_version);
| ^~~~~~~~~~~~~~~~~~~~~~
C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: ./main.o:main.c:(.text+0x386): undefined reference to `ImGui_ImplSDL2_InitForOpenGL'
C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: ./main.o:main.c:(.text+0x395): undefined reference to `ImGui_ImplOpenGL3_Init'
collect2.exe: error: ld returned 1 exit status
make: *** [renderer.exe] Error 1
Here is my makefile (I'm a beginner here so if theres anything stupid going on apologies):
# Compiler definitions
CC = gcc
CXX = g++
# Compiler flags
CFLAGS = -I"C:/Cimgui" -I"C:/Cimgui/imgui" -I"C:/Cimgui" -I"C:/Cimgui/imgui/backends" -I"C:/SDL2/include" -I"C:/cglm-master/include" -I"C:/glew-2.1.0/include" \
-Wall -DGLEW_STATIC -DSDL_STATIC \
-DIMGUI_IMPL_OPENGL_LOADER_GLEW -DIMGUI_DISABLE_OBSOLETE_FUNCTIONS=1
CXXFLAGS = $(CFLAGS) # Same flags for C++ files
# Linker flags
LDFLAGS = -L"C:/Cimgui/build" -L"C:/cglm-master/build" -L"C:/glew-2.1.0/lib/Release/x64" -L"C:/SDL2/lib" \
-Wl,-Bstatic -lSDL2main -lSDL2 -lcglm -lglew32 \
-Wl,-Bdynamic -lopengl32 -ldxguid \
-lmingw32 -mwindows -lm -ldinput8 -ldxguid -ldxerr8 \
-luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 \
-lshell32 -lversion -luuid -static-libgcc \
-lsetupapi -lcfgmgr32 \
-lcimgui
# Target executable
TARGET = renderer.exe
# Define source files
SOURCES = ./main.c
IMGUI_SOURCES = \
C:/Cimgui/cimgui.cpp \
C:/Cimgui/cimgui_impl.cpp \
C:/Cimgui/imgui/imgui.cpp \
C:/Cimgui/imgui/imgui_draw.cpp \
C:/Cimgui/imgui/imgui_widgets.cpp \
C:/Cimgui/imgui/imgui_tables.cpp \
C:/Cimgui/imgui/imgui_demo.cpp \
C:/Cimgui/imgui/backends/imgui_impl_sdl2.cpp \
C:/Cimgui/imgui/backends/imgui_impl_opengl3.cpp
# Convert sources to object files
OBJECTS = $(SOURCES:.c=.o) $(IMGUI_SOURCES:.cpp=.o)
# Default target
all: $(TARGET)
# Link all object files into the executable
$(TARGET): $(OBJECTS)
echo "Objects to link: $(OBJECTS)"
$(CXX) $(OBJECTS) -o $(TARGET) $(LDFLAGS)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
# Run the program
run:
./$(TARGET)
# Clean up
clean:
rm -f $(OBJECTS) $(TARGET)
.PHONY: all clean run
I tried to follow the example CMakeLists.txt thats included with the sdl_opengl cimgui example project as much as possible but for some reason it cannot find these methods. For reference here is my main.c file:
#include <stdio.h>
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <GL/glew.h>
#include <stdbool.h>
#include <cglm/cglm.h>
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
#include <cimgui.h>
#include <cimgui_impl.h>
#include <windows.h>
static int window_width = 640;
static int window_height = 480;
///////////////////////////////////////////////////////////////////////////////
// Global variables for execution status and game loop
///////////////////////////////////////////////////////////////////////////////
static SDL_Window* window = NULL;
SDL_GLContext context = NULL;
static SDL_Renderer* renderer = NULL;
float delta_time = 0;
bool is_running = false;
float previous_frame_time;
//set docking
ImGuiIO* ioptr;
const char* glsl_version = "#version 130";
///////////////////////////////////////////////////////////////////////////////
// Setup function to initialize variables and game objects
///////////////////////////////////////////////////////////////////////////////
int setup(void) {
if(SDL_Init(SDL_INIT_EVERYTHING) != 0){
fprintf(stderr, "Error initializing SDL window");
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_DisplayMode displayMode;
SDL_GetCurrentDisplayMode(0, &displayMode);
// int full_screen_width = displayMode.w;
// int full_screen_height = displayMode.h;
vec3 v = {1.0f, 2.0f, 3.0f};
printf("current vec3: (%f, %f, %f)", v[0],v[1],v[2]);
// //TODO create SDL window
window = SDL_CreateWindow(
"The window into Jamie's madness",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
window_width,
window_height,
SDL_WINDOW_OPENGL
);
if(!window){
fprintf(stderr, "Error creating SDL window");
return false;
}
//TODO create SDL Renderer
renderer = SDL_CreateRenderer(window,-1, 0);
if(!renderer){
fprintf(stderr, "Error creating SDL renderer");
return false;
}
SDL_SetWindowBordered(window,SDL_WINDOWPOS_CENTERED);
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window,context);
glewExperimental = GL_TRUE;
glewInit();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// setup imgui
igCreateContext(NULL);
ioptr = igGetIO();
ioptr->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//ioptr->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
#ifdef IMGUI_HAS_DOCK
ioptr->ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
ioptr->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
#endif
ImGui_ImplSDL2_InitForOpenGL(window, context);
ImGui_ImplOpenGL3_Init(glsl_version);
igStyleColorsDark(NULL);
return true;
}
int main(int argc, char* args[]){
setup();
return 0;
}