Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake not properly linking files after successful build

Tags:

cmake

I have a simple project that I am trying to automate the build with cmake. Things were going just fine until I just ran into a brick wall with the cmake build process. I think it's best if I show you the entire project.

project/
    CMakeLists.txt **[1]**
    build/
    source/
        CMakeLists.txt **[2]**
        main.c
        game/
        CMakeLists.txt **[3]**
        game.c
        game.h

main.c

#include <stdio.h>
#include “game/game.h"

int main(int argc, char const *argv[]) {

  initSdlAccel(480, 320, "this is a test");

  return 0;
}

game.h

#include <stdlib.h>
#include <string.h>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <SDL_mixer.h>

void initSdlAccel(int width, int height, const char *title);

game.c

#include “game.h"

SDL_Window *window;
SDL_Renderer *renderer;

void initSdlAccel(int width, int height, const char *title)
{
  if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
  {
    SDL_Log("sdl failed to init");
    SDL_Quit();
  }

  window = SDL_CreateWindow(title, 100, 100, width, height, SDL_WINDOW_SHOWN);
  if(window == NULL)
  {
    SDL_Log("sdl failed to create window");
    SDL_Quit();
  }

  renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  if(window == NULL)
  {
    SDL_Log("sdl failed to create renderer");
    SDL_Quit();
  }
}

CMakeLists.txt[1]

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

PROJECT(game)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

IF(APPLE)
   #SET(GUI_TYPE MACOSX_BUNDLE)
   SET(INCLUDE_DIRS /Library/Frameworks/SDL2.framework/Headers
                    /Library/Frameworks/SDL2_ttf.framework/Headers
                    /Library/Frameworks/SDL2_mixer.framework/Headers
                    /Library/Frameworks/SDL2_image.framework/Headers)
   INCLUDE_DIRECTORIES ( "${INCLUDE_DIRS}" )
   FIND_LIBRARY(SDL2_LIBRARY Sdl2)

   SET(EXTRA_LIBS ${Sdl2} )
   INCLUDE_DIRECTORIES("${INCLUDE_DIRS}")
ENDIF (APPLE)

ADD_SUBDIRECTORY(source)
ADD_SUBDIRECTORY(source/game)

CMakeLists.txt[2]

PROJECT(launcher)

SET(SRC_FILES main.c)

INCLUDE_DIRECTORIES("${PROJECT_BINARY_DIR}")

ADD_EXECUTABLE(launcher "${SRC_FILES}")
TARGET_LINK_LIBRARIES(launcher game)

CMakeLists.txt[3]

PROJECT(game)

SET(SRC_FILES game.c)

ADD_LIBRARY(game "${SRC_FILES}”)
#
Undefined symbols for architecture x86_64:
  "_SDL_Log", referenced from:
      _initSdlAccel in libgame.a(game.c.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[2]: *** [bin/launcher] Error 1
make[1]: *** [source/CMakeFiles/launcher.dir/all] Error 2
make: *** [all] Error 2

This is a pretty simple or at least should be pretty simple build setup but I just can't get the game.c file to actually use the included SDL files. They are found correctly because if I remove the apple specific code from the main CMakeLists file it doesn't even build.

How can I sort this out?

like image 259
mr oh Avatar asked Feb 10 '23 17:02

mr oh


2 Answers

In CMakeLists.txt[3], you are missing:

TARGET_LINK_LIBRARIES(game ${SDL2_LIBRARY})

Or you could append ${SDL2_LIBRARY} to the TARGET_LINK_LIBRARIES call you have in CMakeLists.txt[2]...

like image 106
DLRdave Avatar answered Mar 18 '23 21:03

DLRdave


You found the SDL libraries but you didn't actually do anything with them. All the Find* modules do is return variables containing the include or library files that are needed.

You link your launcher to the game library but you also need to link it to the SDL libraries the Find_Library call returned to you.

Of course, all of this could be made easier if you used the FindSDL module which returns to you all the variables you should need to locate the library and include files.

like image 23
tpg2114 Avatar answered Mar 18 '23 23:03

tpg2114