Reputation: 81
Before you mark as a duplicate, I've read 8 different questions similar to this one on Stackoverflow, and even more so elsewhere. I would not be posting this if any of those answers solved my problem.
I used this exact template with the SDL2 libraries without an issue, the only changes I made were changing "SDL2" to "Curses" along with the set(CURSES_NEED_NCURSES TRUE)
line. (And this still fails without that line for anyone wondering)
Yes I have it installed, and I can easily compile it with gcc main.c -lncurses
without issue.
cmake_minimum_required (VERSION 2.6)
project (ncurses-practice)
# Version info
set(CMake_ncurses-practice_VERSION_MAJOR 1)
set(CMake_ncurses-practice_VERSION_MINOR 0)
# Common Variables
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(SRC ${CMAKE_SOURCE_DIR}/src)
set(HDRS ${CMAKE_SOURCE_DIR}/headers)
set(CMAKE_C_FLAGS " -Wall")
# Set Ncurses
set(CURSES_NEED_NCURSES TRUE)
find_package(Curses)
# Debug
set(CMAKE_BUILD_TYPE Debug)
# Source Files
set(SRC_FILES
${SRC}/main.c
)
# Included directories
include_directories("src" "headers" ${CURSES_INCLUDE_DIRS})
# Generate Executable
add_executable(a.out ${SRC_FILES})
# Add libraries here after the project name
target_link_libraries(ncurses-practice ${CURSES_LIBARIES})
Upvotes: 1
Views: 1918
Reputation: 1902
find_package(Curses)
will expect FindCurses.cmake
file to be present in your CMAKE_MODULE_PATH.
FindCurses.cmake should find the curses library and set the needed variables. You can use other functions like find_path, find_library inside this FindCurses.cmake to find the curses library. Other way is to write a .pc file and use pkg_check_modules to find this Curses library.
Apart from that, these 2 lines are buggy
add_executable(a.out ${SRC_FILES})
target_link_libraries(ncurses-practice ${CURSES_LIBARIES})
Here add_executable is creating a target called a.out and you are linking the CURSES_LIBRARIES for a target (ncurses-practice) that does not exists.
So change your add_executable to
add_executable(ncurses-practice ${SRC_FILES})
Upvotes: 2
Reputation: 54679
You have a bug in your code:
add_executable(a.out ${SRC_FILES})
target_link_libraries(ncurses-practice ${CURSES_LIBARIES})
target_link_libraries
needs to be given the name of a target, not of the project. So the second line should read target_link_libraries(a.out ${CURSES_LIBARIES})
instead (which is a horrible name for an executable, btw).
I used this exact template with the SDL2 libraries without an issue, the only changes I made were changing "SDL2" to "Curses"
Unfortunately, that is not how find scripts work. While there are certain conventions that CMake expects a well-behaved find script to follow, those are more loose guidelines than strict rules. Hence you usually cannot rely on code that works with one find script to also work with another.
Instead you will always have to check the documentation (and often even the source) of the script that you want to use and carefully tailor the surrounding code to it.
In your case, the relevant documentation is the CMake doc for the FindCurses module, while the sources can be found on Kitware's gitlab.
From this you see that the logic is not very smart. Make sure that the paths of your local installation of curses correspond to what the script expects. If you think that the script's find mechanism could be improved, consider opening a pull request with an improved version.
Also, make sure to check whether any values you use from a find script were actually set before using them in your CMake script.
Also, please consider Tsyvarev's advice to never set the CMAKE_BINARY_DIR
from within a CMake script. This variable is supposed to be set by the user that is building the project and not the project itself. The same is true for CMAKE_BUILD_TYPE
.
Upvotes: 0