1

I use cmake to organize my project, here is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(Game)
set(CMAKE_CXX_COMPILER "llvm-g++")

# Find SDL2 packages
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
find_package(SDL2_ttf REQUIRED)
find_package(SDL2_mixer REQUIRED)

# add Header file
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} ${SDL2_TTF_INCLUDE_DIRS} ${SDL2_MIXER_INCLUDE_DIRS})

# Add source files
set(SOURCES
  main.cpp
  Base/BasePlus.cpp
  )

add_compile_options(-std=c++11)
add_compile_options(-Wall)
add_executable(a.out ${SOURCES})

# link lib
target_link_libraries(a.out ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES} ${SDL2_TTF_LIBRARIES} ${SDL2_MIXER_LIBRARIES})

Then I used cmake command, and it worked well, looks like:

-- Configuring done
-- Generating done
-- Build files have been written to: /Users/Jacket/Documents/GameFramwork/build

But when I tried to run make in build directory, it came out with this:

[ 33%] Linking CXX executable a.out
Undefined symbols for architecture arm64:
  "_IMG_Init", referenced from:
      BasePlus::BasePlus() in BasePlus.cpp.o
  "_IMG_Load", referenced from:
      BasePlus::loadTextureColorKey(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, int, int) in BasePlus.cpp.o
  "_IMG_LoadTexture", referenced from:
      BasePlus::loadTexture(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in BasePlus.cpp.o
  "_IMG_Quit", referenced from:
      BasePlus::~BasePlus() in BasePlus.cpp.o
  "_Mix_CloseAudio", referenced from:
      BasePlus::~BasePlus() in BasePlus.cpp.o
  "_Mix_FreeMusic", referenced from:
      BasePlus::~BasePlus() in BasePlus.cpp.o
  "_Mix_Init", referenced from:
      BasePlus::BasePlus() in BasePlus.cpp.o
  "_Mix_LoadMUS", referenced from:
      BasePlus::loadMusic(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in BasePlus.cpp.o
  "_Mix_OpenAudio", referenced from:
      BasePlus::BasePlus() in BasePlus.cpp.o
  "_Mix_Quit", referenced from:
      BasePlus::~BasePlus() in BasePlus.cpp.o
  "_TTF_CloseFont", referenced from:
      BasePlus::~BasePlus() in BasePlus.cpp.o
  "_TTF_Init", referenced from:
      BasePlus::BasePlus() in BasePlus.cpp.o
  "_TTF_OpenFont", referenced from:
      BasePlus::loadFont(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int) in BasePlus.cpp.o
  "_TTF_Quit", referenced from:
      BasePlus::~BasePlus() in BasePlus.cpp.o
  "_TTF_RenderText_Blended_Wrapped", referenced from:
      BasePlus::loadFontToTexture(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, SDL_Color) in BasePlus.cpp.o
  "_TTF_SetFontHinting", referenced from:
      BasePlus::loadFont(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int) in BasePlus.cpp.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [a.out] Error 1
make[1]: *** [CMakeFiles/a.out.dir/all] Error 2
make: *** [all] Error 2

I guess it was caused by linking problem, and I did find some answers on StackOverFlow, but they just not work for me, it confuses me for a few days, while SDL_Init() function works but the other not.

I am using MacOS M1, downloaded sdl2_image ttf mixer from GitHub and dragged it to /Library/Frameworks, by the way, all the framework runs well in Xcode but not with command line

genpfault
  • 51,148
  • 11
  • 85
  • 139
Necromancy
  • 19
  • 4
  • 1
    Have you checked that `SDL2_LIBRARIES` and other `SDL2_*_LIBRARIES` variables, which you use in your code, are actually **non-empty**? `find_package` could work in two modes - Find scripts or config script - and variables are normally defined only in Find scripts. – Tsyvarev Dec 23 '22 at 14:18
  • @Tsyvarev Yes, I found it empty, how can I add the path for cmake to search? I tried to use```list(APPEND CMAKE_PREFIX_PATH "/Library/Frameworks/")``` But it does not search subdirectories, I also tried to use ```find_path find_library``` to specify which path to find them, but I don't know if it was the right way to do it, and this method can not be used cross platform – Necromancy Dec 24 '22 at 08:10
  • No, you misunderstand: the variables are empty not because `find_package` fails, the variables are empty because `find_package` defines some **other** things for use. Most likely, it defines IMPORTED targets, as in [that answer](https://stackoverflow.com/a/51723603/3440745). You could also try approaches from other answers from the same question. – Tsyvarev Dec 24 '22 at 19:32

1 Answers1

1

I finally solved the problem by using the recommended way in README file which is contain in SDL2.dmg, what I learned online is outdated usage, either too old to use or they are not suitable for MacOS, Here is my solution

First, the README file indicates this:

Use in CMake projects:
SDL2.framework can be used in CMake projects using the following pattern:

find_package(SDL2 REQUIRED COMPONENTS SDL2)
add_executable(my_game ${MY_SOURCES})
target_link_libraries(my_game PRIVATE SDL2::SDL2)

So I write my CMakeLists.txt looks like:

# Find SDL2 packages
find_package(SDL2 REQUIRED COMPONENTS SDL2)
find_package(SDL2_image REQUIRED)
find_package(SDL2_ttf REQUIRED)
find_package(SDL2_mixer REQUIRED)

add_executable(a.out ${SOURCES})

# link lib
target_link_libraries(a.out PRIVATE SDL2::SDL2 SDL2_image::SDL2_image SDL2_ttf::SDL2_ttf SDL2_mixer::SDL2_mixer)

And they just work for me!!

Necromancy
  • 19
  • 4