I've been working on a hobby project of mine programmed in C++ on macOS, and as a beginner in CMake, I tried to move away from find_package due to issues with getting it to prioritize vendored libraries.
I re-wrote my CMake script to try to streamline the process of adding subdirectories, and I didn't get any errors when I generated the makefiles. When I tried to actually compile the program, however, my first library (SDL) compiled successfully, but failed to link to my executable with the following error:
[ 49%] Linking C shared library libSDL2-2.0.dylib
Undefined symbols for architecture x86_64:
"_CHHapticDynamicParameterIDHapticIntensityControl", referenced from:
-[SDL_RumbleMotor setIntensity:] in SDL_mfijoystick.m.o
"_CHHapticEventParameterIDHapticIntensity", referenced from:
-[SDL_RumbleMotor setIntensity:] in SDL_mfijoystick.m.o
"_CHHapticEventTypeHapticContinuous", referenced from:
-[SDL_RumbleMotor setIntensity:] in SDL_mfijoystick.m.o
"_GCControllerDidConnectNotification", referenced from:
_IOS_JoystickInit in SDL_mfijoystick.m.o
_IOS_JoystickQuit in SDL_mfijoystick.m.o
...
"_OBJC_CLASS_$_CHHapticDynamicParameter", referenced from:
objc-class-ref in SDL_mfijoystick.m.o
"_OBJC_CLASS_$_CHHapticEvent", referenced from:
objc-class-ref in SDL_mfijoystick.m.o
"_OBJC_CLASS_$_CHHapticEventParameter", referenced from:
objc-class-ref in SDL_mfijoystick.m.o
"_OBJC_CLASS_$_CHHapticPattern", referenced from:
objc-class-ref in SDL_mfijoystick.m.o
"_OBJC_CLASS_$_GCColor", referenced from:
objc-class-ref in SDL_mfijoystick.m.o
"_OBJC_CLASS_$_GCController", referenced from:
objc-class-ref in SDL_mfijoystick.m.o
"_OBJC_CLASS_$_GCControllerAxisInput", referenced from:
objc-class-ref in SDL_mfijoystick.m.o
"_OBJC_CLASS_$_GCControllerButtonInput", referenced from:
objc-class-ref in SDL_mfijoystick.m.o
ld: symbol(s) not found for architecture x86_64
This appears to be a list of the first twenty or so functions in alphabetical order, leading me to believe that it's somehow unable to find any of the functions. I did notice that most of the "referenced from" locations mention iOS, though, so it's also possible that I'm accidentally including iOS-related functions somehow. My CMake script is as follows:
cmake_minimum_required(VERSION 3.10)
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64")
set(CMAKE_MACOSX_RPATH 1)
set(OutputPath "${CMAKE_SOURCE_DIR}/bin/${CMAKE_SYSTEM_NAME}")
set(CMAKE_ARCHIVE_OUTPUT_DIR "${OutputPath}/staticlibs")
set(CMAKE_LIBRARY_OUTPUT_DIR "${OutputPath}")
set(CMAKE_RUNTIME_OUTPUT_DIR "${OutputPath}")
set(CMAKE_FIND_FRAMEWORK NEVER)
set(TGUI_BACKEND SDL_RENDERER)
set(TGUI_BUILD_FRAMEWORK FALSE)
project(Tutorial VERSION 1.1
DESCRIPTION "Project"
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
#
# Setting lists for convenience:
#
set(SourceList
src/main.cpp
src/graphics.cpp
src/main.h
src/graphics.h
src/version.h
src/files.cpp
src/files.h
src/mainExclusive.h
src/include/tinyfiledialogs.cpp
src/include/tinyfiledialogs.h
)
set (Libraries
src/include/SDL2
src/include/SDL2_image
src/include/SDL2_ttf
src/include/TGUI-1.3.0
)
set (LibraryNames
SDL2
SDL2_image
SDL2_ttf
TGUI
)
add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${SourceList})
# Read the Libraries list to determine subdirectories to add
foreach(Project IN LISTS Libraries)
#include_directories(${Project})
if(NOT TARGET ${Project})
add_subdirectory(${Project})
endif()
endforeach()
# Read LibraryNames to link the libraries by their actual name
foreach(Name IN LISTS LibraryNames)
target_link_libraries(${PROJECT_NAME} ${Name})
endforeach()
Never mind it being generally messy from being referenced from several tutorials, and also me naming my dependencies folder "include" for whatever reason, I'm completely lost as to what causes it to fail at linking.
I tried including the library directories prior to adding the subdirectory, but it didn't seem to make a difference. I also tried to link the libraries in the "for each project in Libraries" loop instead of the LibraryNames loop, but that just completely skips over the dependencies (probably it's looking for libraries that are named "src/include/[library directory]").
If anyone can help me, it would be much appreciated, as I've been stuck on this for days.
Sorry for ghosting the topic for so long! I tried descherjm's suggestion of using find_package
with the package source under PATH
and while setting NO_CMAKE_SYSTEM_PATH
. Surprise, it works. I swore I looked over the CMake docs multiple times, how did I not notice these useful parameters?!
I guess at least other people with similarly low reading retention now have this question to be pointed to...