4

I am trying to run a program that opens a window. the purpose is to get the program started opening a window is the start of all programs right?

But when I run my code for some reason I get this error:

Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

However, in my code I do have the main() function so why am I getting this error?

This is my code:

#include <SDL2/SDL.h>
#include <SDL2_image/SDL_image.h>
#include <SDL2_ttf/SDL_ttf.h>
#include <stdio.h>

int main(){
    if(SDL_Init( SDL_INIT_EVERYTHING ) < 0){
        std::cout << "error 1\n";
        std::cout << SDL_GetError();
        std::cout << "\n";
        return -1;
        }
    if(TTF_Init() < 0){
        std::cout << "error 2\n";
        std::cout << TTF_GetError();
        std::cout << "\n";
        return -1;
    }
    SDL_Window* window = SDL_CreateWindow("test", 0, 0, 500, 500, 0);
    if(!window){
        std::cout << "error 3\n";
        std::cout << SDL_GetError();
        std::cout << "\n";
        return -1;
    }
    int windowid = SDL_GetWindowID(window);
    SDL_Renderer* Renderer = SDL_CreateRenderer(window, -1, 0);
    running = true;
    SDL_Event event;
    while(running){
        while(SDL_PollEvent(&event)){
            if(event.type == SDL_WindowEvent){
                if(event.window.windowID == windowid){
                    if(event.window.type == SDL_WindowClose){
                        Destroywindow(window);
                        running = false;
                    }
                }
            }
        }
    }
    return 0;
}

my make file looks like this:

#!/bin/bash

brew update
brew install sdl2
g++ -o /Users/mikahshattuck/noneproject/none2019-05-0909-22- 
14:2:/none.app/Contents/MacOS/mainrun.cpp -I /Library/Frameworks -l 
SDL2
exit 0

this is the full out:

Already up-to-date.
Warning: sdl2 2.0.9_1 is already installed and up-to-date
To reinstall 2.0.9_1, run `brew reinstall sdl2`
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see 
invocation)
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.

[Process completed]

thank you in advance

Mikah
  • 326
  • 1
  • 11
  • 3
    How are you compiling? Can you post the clang command you're using? – scohe001 May 10 '19 at 18:48
  • what do you mean clang command? – Mikah May 10 '19 at 18:49
  • 1
    Clearly, the source you've presented *does* have a `main()` function. Either it is not the source relevant to the error you've presented, or the problem is related to how you've attempted to compile the program. So how did you attempt to compile the program? – John Bollinger May 10 '19 at 18:50
  • SDL apparently does some hackery around with `main`, defining it as a macro and providing its own; google "SDL main". – Angew is no longer proud of SO May 10 '19 at 18:51
  • 4
    "opening a window is the start of all programs right?" - No. There are a *ton* of very useful console applications that never open any window / GUI. Take `grep` as an example; if it ever opened a window I would be very unhappy. – Jesper Juhl May 10 '19 at 18:51
  • the make file is bash and the file be run by the make file is c++ – Mikah May 10 '19 at 18:52
  • Don't wrap the lines in your bash script. We need to see it exactly as it is in the file. – Rob K May 10 '19 at 18:58
  • Also, please include the entire output from the make file invocation. – Rob K May 10 '19 at 19:00
  • 1
    Related: [Why SDL defines main macro?](https://stackoverflow.com/questions/11976084/why-sdl-defines-main-macro) – John Bollinger May 10 '19 at 19:01
  • I know that not all programs open windows but this is an application so it should open a window all applications open windows. – Mikah May 11 '19 at 21:02

1 Answers1

4

When using SDL on macOS or Windows, you need to add -Dmain=SDL_main to your compile flags and -lSDL2main to your link flags. Since you're using Homebrew, you can make it easier and just use pkg-config to get the correct flags. Use this compiler command as a template and adapt it to your needs:

g++ $(pkg-config --cflags sdl2) -I /Library/Frameworks source.cpp -o output_executable $(pkg-config --libs sdl2)

However, it seems you are also using SDL_ttf, not just plain SDL. In this case, you should probably use SDL2_ttf instead of sdl2 as the package argument of pkg-config:

g++ $(pkg-config --cflags SDL2_ttf) -I /Library/Frameworks source.cpp -o output_executable $(pkg-config --libs SDL2_ttf)

The SDL2_ttf package depends on the sdl2 package, so using SDL2_ttf will also emit the needed flags for sdl2.

The names of the pkg-config packages correspond to *.pc files installed by Homebrew into /usr/local/lib/pkgconfig.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
  • Other sources suggest that SDL headers provide the macro definition themselves. In any event, it seems likely that missing `-lSDL2main` is indeed the central problem. – John Bollinger May 10 '19 at 19:03
  • @JohnBollinger If you use pkg-config, the correct flags will be used. – Nikos C. May 10 '19 at 19:04
  • that worked whoever how would I do that for sdl image and sdl ttf? – Mikah May 10 '19 at 19:23
  • @MikahShattuck You can pass both arguments at the same time: `pkg-config --cflags SDL2_ttf SDL2_image` (and same for `--libs`). – Nikos C. May 10 '19 at 19:29
  • @MikahShattuck I forgot whether or not Homebrew installs pkg-config by default or not. If it doesn't, just install it yourself: `brew install pkg-config` – Nikos C. May 10 '19 at 20:46
  • homebrew does not but I figured that out on my own. – Mikah May 12 '19 at 12:54