2015-06-25 3 views
4

У меня есть простой проект, который я пытаюсь автоматизировать сборку с помощью cmake. Все прошло отлично, пока я не столкнулся с кирпичной стеной с процессом сборки cmake. Я думаю, что лучше всего показать вам весь проект.CMake не правильно связывает файлы после успешной сборки

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 

Это довольно простая или, по крайней мере, должна быть довольно простая установка сборки, но я просто не могу получить файл game.c для фактического использования включенных SDL-файлов. Они найдены правильно, потому что, если я удалю код конкретного яблока из основного файла CMakeLists, он даже не будет создан.

Как я могу разобраться в этом?

ответ

5

В CMakeLists.txt [3], вам не хватает:

TARGET_LINK_LIBRARIES(game ${SDL2_LIBRARY}) 

Или вы могли бы добавить $ {} SDL2_LIBRARY к TARGET_LINK_LIBRARIES называть вас в CMakeLists.txt [2] ...

+0

Благодарим вас за это, это позволило программе скомпилировать и запустить. Кажется, что с cmake я могу установить эти настройки в нескольких местах, и это немного запутывает меня, так как я новичок в cmake. Большое спасибо за демонстрацию кода и краткое объяснение! –

3

Вы нашли библиотеки SDL, но на самом деле ничего не сделали с ними. Все модули Find* представляют собой возвращаемые переменные, содержащие необходимые файлы include или библиотеки.

Вы связываете свою пусковую установку с библиотекой игр, но вам также необходимо связать ее с библиотеками SDL, которые вызвал запрос Find_Library.

Конечно, все это можно сделать проще, если вы использовали модуль FindSDL, который возвращает вам все переменные, необходимые для поиска библиотеки и включения файлов.

+0

Основная причина, по которой я устанавливаю проект таким образом, потому что find_package (sdl), кажется, возвращает только sdl, тогда как мне также понадобятся дополнительные библиотеки, sdl_image, sdl_ttf и т. Д.Он не найдет тех же способов, что это работает на Mac, я должен был бы включить , а на каждой другой платформе это просто включает , вы говорите, что я фактически не использую найденные библиотеки, можете ли вы объяснить это более четко? –

0

Чтобы усилить предыдущий ответ, EXTRA_LIBS установлен, но никогда не упоминается. Это не волшебная переменная, вы должны ее использовать.