无法使用 CMake 和 ncurses 进行编译

Posted

技术标签:

【中文标题】无法使用 CMake 和 ncurses 进行编译【英文标题】:Can't compile with CMake and ncurses 【发布时间】:2017-04-07 20:03:47 【问题描述】:

我知道已经发布了类似的问题,但我看不出它们与我的案例有什么关系。我会先说我对 CMake 不是很熟悉,所以这完全有可能是一个快速修复,我只是看不到它!

我正在合作一个项目,昨天我的队友将 ncurses 库添加到项目中以构建终端 GUI。自从添加了 ncurses 以来,我一直无法编译我的项目。但是,我确实安装了所有 6 个 ncurses-* 包,所以它应该可以在我的机器上运行。

我从我们的 GitHub 存储库中下载了最新版本的 master 分支,它可以在他的机器上完美编译和运行。但是它甚至不会在我的上编译。

系统: Linux Mint 18.1 肉桂 CMake 版本 3.5.1

我尝试过的事情: 我删除了 CMakeCache.txt 并重新加载了它 我删除了我的整个 CMake 构建目录并重新制作了

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
project(irc)

set(SHARED_FLAGS " -Wall -Wextra -Wshadow -Werror -g -D_POSIX_C_SOURCE=200809L -lncurses")
set(CMAKE_C_FLAGS "-std=c11 $SHARED_FLAGS")
set(CMAKE_CXX_FLAGS "-std=c++11 $SHARED_FLAGS")

include_directories(include)

add_library(client_core SHARED src/client/irc_client.c)

add_executable(client src/client/irc_client_gui.c)
add_executable(server src/server/irc_server.c)

// SOLUTION - MISSING LINE
target_link_libraries(client ncurses)

install(FILES include/irc_client.h DESTINATION include)
install(FILES include/irc_server.h DESTINATION include)

CMakeOutput:

CMakeFiles/client.dir/src/client/irc_client_gui.c.o: In function `main':
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:17: 
undefined reference to `initscr'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:18: 
undefined reference to `stdscr'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:18: 
undefined reference to `stdscr'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:18: 
undefined reference to `stdscr'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:18: 
undefined reference to `stdscr'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:19: 
undefined reference to `mvprintw'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:21: 
undefined reference to `stdscr'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:21: 
undefined reference to `wgetnstr'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:22: 
undefined reference to `LINES'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:22: 
undefined reference to `mvprintw'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:23: 
undefined reference to `stdscr'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:23: 
undefined reference to `wgetch'
/home/chrisjansson/Documents/irc/src/client/irc_client_gui.c:24: 
undefined reference to `endwin'
collect2: error: ld returned 1 exit status
CMakeFiles/client.dir/build.make:94: recipe for target 'client' failed
make[2]: *** [client] Error 1
CMakeFiles/Makefile2:104: recipe for target 'CMakeFiles/client.dir/all' 
failed
make[1]: *** [CMakeFiles/client.dir/all] Error 2
Makefile:127: recipe for target 'all' failed
make: *** [all] Error 2

有趣的是,如果我将 irc_client_gui.c 复制/粘贴到我机器上的其他地方,用 gcc 手动编译并运行它,它就可以完美运行。所以问题不是我的机器,而是 CMake 试图编译我的整个项目。有任何想法吗?非常感谢!

【问题讨论】:

So the issue isn't my machine, it's something with CMake trying to compile my entire project. - 您项目的CMakeLists.txt 文件的问题,但您没有显示它。 @Tsyvarev 哎呀,我刚刚将它添加到顶部。谢谢! 如何运行make VERBOSE=Y 以便您可以准确地看到编译器/链接器是如何被调用的?我强烈怀疑-lncurses 没有在链接器步骤中传递,因为您没有使用target_link_libraries 之类的东西。未定义的引用错误通常是由链接期间缺少 -l 参数引起的。 @DavidGrayson 你在现场,我添加了一个'target_link_libraries'并编译。谢谢!我会将该行添加到顶部,以便其他人可以看到解决方案。 【参考方案1】:

解决办法是像这样添加一行:

target_link_libraries(client ncurses)

这告诉 CMake,当它链接 client 目标时,它应该使用 -lncurses 选项来链接 ncurses 库。

【讨论】:

以上是关于无法使用 CMake 和 ncurses 进行编译的主要内容,如果未能解决你的问题,请参考以下文章

CentOS 6.4 源码安装MySQL 5.6

MySQL在linux上(cmake)的source code安装方法

使用 ncurses 和 cmake 链接期间未定义的引用

MySQL安装与配置(5.6.12,参考乐沙弥博客,未完成)

php编译安装

cmake编译安装mysql