On macOS, if I compile with
clang -I. -framework OpenGL main.cpp glad.c /usr/local/Cellar/glfw/3.3.1/lib/libglfw.3.3.dylib
I can build and run the generated executable from the following code:
#define GL_SILENCE_DEPRECATION
#include <stdio.h>
#include "glad/glad.h"
#include "/usr/local/Cellar/glfw/3.3.1/include/GLFW/glfw3.h"
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClearColor(0.9, 0.1, 0.1, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
But I would like to build using a Makefile, so I prepared
CC = clang
XXFLAGS = -g -Wall -v
CPPFLAGS = -I.
LDLIBS = -lm -L/usr/local/Cellar/glfw/3.3.1/lib -lglfw
LDFLAGS = -framework OpenGL
OBJS = main.o glad.o
PROGRAM = main
$(PROGRAM): $(OBJS)
$(CXX) $^ $(XXFLAGS) $(CPPFLAGS) $(LDLIBS) $(LDFLAGS) -o $#
clean:
-rm -f *.o
distclean: clean
-rm -Rf $(PROGRAM)
It actually makes the executable but when I run it I get
$ ./main
Segmentation fault: 11
So I guess there is something wrong in the Makefile, right?
$ make -n
c++ -I. -c -o main.o main.cpp
clang -I. -c -o glad.o glad.c
c++ main.o glad.o -g -Wall -v -I. -lm -L/usr/local/Cellar/glfw/3.3.1/lib -lglfw -framework OpenGL -o main
You didn't define the rule to build OBSJ, so make used its built-in rules. The PROGRAM rule only links object files, and there's no point specifying CPPFLAGS there.
.PHONNY: all
all: clean a.out
a.out:
clang++ -I glad/include -F /Library/frameworks -framework OpenGL main.cpp glad/src/glad.c /usr/local/Cellar/glfw/3.3.1/lib/libglfw.3.3.dylib
clean:
rm a.out
References:
https://www.gnu.org/software/make/manual/make.html
https://opensource.com/article/18/8/what-how-makefile
Related
I've been trying to set up a build environment for OpenGL using glfw3 and GLAD. I'm currently using WSL2 Ubuntu with an X Server for compilation and a makefile.
However, when I run my make I receive the following error:
src/glad.c:25:10: fatal error: glad/glad.h: No such file or directory
25 | #include <glad/glad.h>
This is odd to me because it seems that the makefile is able to compile the main.cpp file and create a main.o despite also including "glad/glad.h"
File structure:
-HelloTriangle
--include
---glad
----glad.h
---KHR
----khrplatform.h
--src
---glad.c
---main.cpp
--makefile
This is my make file:
BASE_OBJS = main.o glad.o
SRC_PATH = src
OBJS = $(addprefix $(SRC_PATH)/, $(BASE_OBJS))
CXX = g++
CXXFLAGS = -g -Iinclude
LDFLAGS =
LDLIBS = -lglfw -lGL -lX11 -lpthread -lXrandr -lXi -ldl
HelloTriangle: $(OBJS)
$(CXX) -o $# $(LDFLAGS) $^ $(LDLIBS)
clean:
rm $(OBJS)
This is my main.cpp:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
/*
Function to handle window resizing
*/
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
int main() {
/*
Initialize GLFW
Sets version to Core profile 3.3
*/
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
/*
Initialize a window context for OpenGL
Defines the windows width, height, and title
*/
GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Hello Triangle", NULL, NULL);
if(window == NULL) {
std::cout << "Failed to create GLFW window" <<std::endl;
glfwTerminate();
return -1;
}
/*
Initialize GLAD
Handles OS-specific function pointers
*/
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
/*
Handle window resizing
*/
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
/*
Render loop
*/
while(!glfwWindowShouldClose(window)) {
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); }
You seem to set the CXXFLAGS (for the C++ compiler), but your glad.c is compiled with the C-compiler (which checks CFLAGS)
I've been struggling with getting SDL and SDL_ttf to work together. My minimal reproducible case (down below) works in VC++ but for the life of me I can't get it to work in a MinGW environment.
SDL version: 2.0.10 (latest at moment of writing)
SDL_ttf version: 2.0.15 (latest at moment of writing)
My set up looks like this:
Copied SDL and SDL_ttf lib and include folders to my project root.
Set up my link and include in my Makefile like so:
SRC_DIR=./app/src
INC_DIR=./app/inc
OBJ_DIR=./.obj
BUILD_DIR=./build
NAME=$(BUILD_DIR)/out
all: $(NAME)
CC=gcc
CXX=g++
CXXFLAGS=-Wall -Wextra -pedantic --std=c++17 -g
# Objects to build
STNAMES=\
main \
OBJECTS=$(patsubst %,$(OBJ_DIR)/%.o, $(STNAMES))
# Windows specific settings
ifeq ($(OS), Windows_NT)
LINK=\
-L./SDL2/lib \
-L./SDL2_ttf/lib \
-lmingw32 \
-lSDL2main \
-lSDL2 \
-lSDL2_ttf \
-lstdc++ \
INCLUDE=\
-I$(INC_DIR) \
-I./SDL2/include \
-I./SDL2_ttf/include \
define mkdir =
if not exist "$(1)" mkdir "$(1)"
endef
define rmdir =
if exist "$(1)" del /S/Q "$(1)"
endef
EXECUTABLE=$(NAME).exe
# macOS specific settings
# UNTESTED, assumes dependencies are installed with brew
else
LINK=$(shell sdl2-config --libs) -lc++
INCLUDE=\
-I$(shell brew --prefix)/include/SDL2 \
define mkdir
mkdir -p $(1)
endef
define rmdir =
rm -rf $(1)
endef
EXECUTABLE=$(NAME)
endif
$(NAME): $(OBJECTS)
#$(call mkdir,$(BUILD_DIR))
$(CC) -o $# $(OBJECTS) $(LINK)
#$(EXECUTABLE)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
#$(call mkdir,$(OBJ_DIR))
#$(CXX) -o $# -c $< $(CXXFLAGS) $(INCLUDE)
re:
#$(call rmdir,$(OBJ_DIR))
make
Added the dlls to MinGW's bin folder.
Here's a minimal reproducible test case which works for me on Visual Studio, but not on MinGW:
#include <iostream>
#include <SDL.h>
#include <SDL_ttf.h>
void drawText(SDL_Renderer* renderer, TTF_Font* font, int x, int y, const char* text) {
auto surface = TTF_RenderText_Solid(font, text, SDL_Color{ 255, 255, 255, 255 });
auto texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_Rect dstRect = { x, y, surface->w, surface->h };
SDL_RenderCopy(renderer, texture, NULL, &dstRect);
SDL_DestroyTexture(texture);
SDL_FreeSurface(surface);
}
int main(int argc, char* argv[]) {
(void)argc;
(void)argv;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("some title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1920, 1080, SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
TTF_Init();
bool running = true;
SDL_Event event;
auto font = TTF_OpenFont("assets/courier_prime.ttf", 36);
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
running = false;
}
SDL_SetRenderDrawColor(renderer, 25, 25, 25, 255);
SDL_RenderClear(renderer);
drawText(renderer, font, 10, 10, "Test string");
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255 );
auto rect = SDL_Rect{10, 100, 110, 200};
SDL_RenderFillRect(renderer, &rect);
SDL_RenderPresent(renderer);
}
TTF_CloseFont(font);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
TTF_Quit();
SDL_Quit();
return 0;
}
Regardless of where I place that SDL_RenderFillRect (before or after the drawText), the only thing I see is the text. The Rectangle is no longer visible.
I'm currently dealing with a mixed OS dev environment (mac and windows), hence why I'd like it to build on both using make.
Seems like it was an issue with SDL_RENDERER_ACCELERATED and openGL not being linked. Linking openGL did not fix the issue, however, swapping to the software renderer (SDL_RENDERER_SOFTWARE) did fix the rendering bug. Very strange that it does work on VS though. I guess that'll remain a mystery...
i'm trying to use the SDL1.2 librairie with c++ files but, i can't compile.
i'm on windows and when i want to compile, the linking cannot be done.
i made a makefile :
CC = gcc
CFLAGS = -Wall -I include
LDFLAGS = -L/lib -lmingw32 -lSDLmain -lSDL -lSDL_image -mwindows
Programme : main.o
$(CC) main.o -o Programme $(LDFLAGS)
main.o : main.cpp
$(CC) $(CFLAGS) -c main.cpp -o main.o
clean :
del -rf *.o
mrproper : clean
del Programme
and here is my main.cpp :
#include <stdio.h>
#include <SDL/SDL.h>
void pause();
int main(int argc, char *argv[])
{
SDL_Surface *ecran = NULL, *imageDeFond = NULL;
SDL_Rect positionFond;
positionFond.x = 0;
positionFond.y = 0;
SDL_Init(SDL_INIT_VIDEO);
ecran = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE);
SDL_WM_SetCaption("Chargement d'images en SDL", NULL);
imageDeFond = SDL_LoadBMP("lac_en_montagne.bmp");
SDL_BlitSurface(imageDeFond, NULL, ecran, &positionFond);
SDL_Flip(ecran);
pause();
SDL_FreeSurface(imageDeFond);
SDL_Quit();
return EXIT_SUCCESS;
}
void pause()
{
int continuer = 1;
SDL_Event event;
while (continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
}
}
}
and when i run the makefile with the command :
mingw32-make
here is the output :
C:\Users\summire\Desktop\a day in hell>mingw32-make
gcc main.o -o Programme -L/lib -lmingw32 -lSDLmain -lSDL -lSDL_image -mwindows
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lSDLmain
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lSDL
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lSDL_image
collect2.exe: error: ld returned 1 exit status
mingw32-make: *** [makefile:6: Programme] Error 1
can someone please explain me what am i doing wrong ?
also, here is my arborescence :
/
img/
example1.png
include/
SDL/
all the .h files for SDL
lib/
libSDL.a
libSDLmain.a
src/
(nothing yet)
I just started learning c++ and makefiles. Now I'm stuck.
There seem to be dozens of questions like this, but I can't figure out which answer applies to my situation. This answer is probably obvious. Some clues for where to look and reasons for what I am doing is wrong would be greatly appreciated!
This is my error:
Undefined symbols for architecture x86_64:
"App::init(char const*, int, int, int, int, bool)", referenced from:
_main in main.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: *** [../out/MYAPP] Error 1
This is my code:
main.cpp
#include "App.h"
// our App object
App* a_app = 0;
int main(int argc, char* argv[])
{
a_app = new App();
a_app->init("Hello World", 100, 100, 640, 480, true);
//...etc more code
return 0;
}
App.h
#ifndef __App__
#define __App__
#include <SDL2/SDL.h>
class App
{
public:
App(){}
~App(){}
bool init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen);
//..etc
private:
};
#endif /* defined(__App__) */
App.cpp
#include "App.h"
#include <iostream>
using namespace std;
bool App::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen)
{
// attempt to initialize SDL
if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
cout << "SDL init success \n";
int flags = 0;
if(fullscreen)
{
flags = SDL_WINDOW_FULLSCREEN;
}
// init the window
m_pWindow = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
//...etc
}
else
{
cout << "SDL init fail \n";
return false; // SDL init fail
}
cout << "SDL init success \n";
m_bRunning = true; // everything inited successfully, start the main loop
return true;
}
And finally my makefile
CXX = clang++
SDL = -framework SDL2 -framework SDL2_image
INCLUDES = -I ~/Library/Frameworks/SDL2.framework/Headers -I ~/Library/Frameworks/SDL2_image.framework/Headers
CXXFLAGS = -Wall -c -std=c++11 $(INCLUDES)
LDFLAGS = $(SDL) -F ~/Library/Frameworks/
SRC = src
BUILD = build
OUT = ../out
EXE = $(OUT)/MYAPP
OBJECTS = $(BUILD)/main.o $(BUILD)/App.o
all: $(EXE)
$(EXE): $(OBJECTS) | $(OUT)
$(CXX) $(LDFLAGS) $< -o $#
$(BUILD)/%.o : $(SRC)/%.cpp | $(BUILD)
$(CXX) $(CXXFLAGS) $< -o $#
$(BUILD):
mkdir -p $(BUILD)
$(OUT):
mkdir -p $(OUT)
clean:
rm $(BUILD)/*.o && rm $(EXE)
You are not linking all the object files.
$(CXX) $(LDFLAGS) $< -o $#
should be
$(CXX) $(LDFLAGS) $^ -o $#
since the $< pseudo-variable expands to only the first dependency, which is main.o. That matches with the linker error.
In fact, making this modification alone makes the error go away on my machine.
I really need help on getting a simple GTK program in c++ running using MinGW. Here's my program:
# Makefile for Hello World Program (lab0).
all: lab0
lab0: lab0.o
g++ -Wall lab0.o -o lab0 -L C:/Users/Vic/Desktop/MinGW/lib -lgtk
lab0.o: lab0.c
g++ -Wall -I C:/Users/Vic/Desktop/MinGW/include/gtk-2.0/gtk -c lab0.c -o lab0.o
Program:
#include <gtk/gtk.h>
int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *label;
gtk_init (&argc, &argv);
/* create the main, top level, window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* give it the title */
gtk_window_set_title (GTK_WINDOW (window), "Hello World");
/* Connect the destroy signal of the window to gtk_main_quit
* When the window is about to be destroyed we get a notification and
* stop the main GTK+ loop
*/
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
/* Create the "Hello, World" label */
label = gtk_label_new ("Hello, World");
/* and insert it into the main window */
gtk_container_add (GTK_CONTAINER (window), label);
/* make sure that everything, window and label, are visible */
gtk_widget_show_all (window);
/* start the main loop, and let it rest there until the application is closed */
gtk_main ();
return 0;
}
when i compile this using minGW i get this error:
g++ -Wall lab0.o -o lab0 -LC:/users/vic/desktop/mingw/lib -lgtk
/bin/Id: cannot find -lgtk
collect2: Id returned 1 exit status
make: *** [lab0] Error 1
I need to fix this problem and I need to figure out how to run gtk from my makefile.
Ideally, you would use pkg-config to help you find the header and library paths:
g++ -Wall lab0.o -o lab0 `pkg-config --cflags --libs gtk+-win32-2.0`
Or just the library path:
g++ -Wall lab0.o -o lab0 -LC:/users/vic/desktop/mingw/lib -lgtk `pkg-config --libs gtk+-win32-2.0`