【问题标题】:Clang on macOS fails linking lmenu from ncursesmacOS 上的 Clang 无法从 ncurses 链接 lmenu
【发布时间】:2019-06-16 19:35:58
【问题描述】:

我是使用 ncurses 库的新手,所以我一直在尝试重新创建此页面上的一些示例,http://www.tldp.org/HOWTO/NCURSES-Programming-HOWTO/index.html

我得到了关于创建菜单的部分,特别是示例 21。我编写的程序适用于 Linux,特别是 Ubuntu 18.04,但是当我使用菜单库时我无法编译。我使用 JUST ncurses 编写的所有其他示例程序都可以正常编译,没有问题,只是在我尝试使用 Menu 库时。

我用来在 Linux 和 macOS 上构建的命令是,

gcc libmenutest.c -o test -lmenu -lncurses

我尝试移动 -lmenu -lncurses 并更改 macOS 上的顺序,但没有成功。我已经通过 brew 安装了 ncurses,并尝试使用 brew 中的 gcc-8,但也没有成功。

我正在运行全新安装的 macOS 和最新的命令行工具。我可以在/usr/lib 中看到 libmenu,与 libncurses 相同。所以我真的很困惑为什么编译器找不到它。

这是我一直在尝试诊断问题的一些测试代码。

#include <curses.h>
#include <menu.h>
#include <stdlib.h>

#define ARRAY_SIZE(a) (sizeof a / sizeof a[0])

int main (void)
{
  int i;
  int nchoices;

  char *choices[] = {
    "Choice 1", "Choice 2", "Choice 3", "Exit", (char *) NULL,
  };

  // Test that the types are present, this should test for the include headers
  ITEM **items;
  MENU *menu;
  WINDOW *win;

  // This will test for includes and to see if libncurses can be linked
  initscr ();
  noecho ();
  cbreak ();
  keypad (stdscr, TRUE);

  // this bit will test for libmenu include and if it can be linked
  nchoices = ARRAY_SIZE (choices);
  items = calloc (nchoices, sizeof (ITEM *));
  if (items == NULL) exit (1);
  for (i = 0; i < nchoices; i++)
    items[i] = new_item (choices[i], choices[i]);

  // write smarmy message to screen :^^^^^^)
  printw ("This worked :^)");
  refresh ();
  getch ();

  // clean up
  for (i = 0; i < nchoices; i++)
    free_item (items[i]);
  endwin ();

  return 0;
}

这是我现在得到的输出......

Undefined symbols for architecture x86_64:
  "_free_item", referenced from:
      _main in libmenutest-0f0c39.o
  "_new_item", referenced from:
      _main in libmenutest-0f0c39.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

【问题讨论】:

    标签: c macos menu clang ncurses


    【解决方案1】:

    您可以执行以下操作:

    brew install ncurses
    

    由于 macOS 已经包含 ncurses 版本,brew 将其替代版本安装在 /usr/local/opt/ncurses

    为了让编译器和链接器可以访问它,您的构建命令现在应该如下所示:

    gcc -I/usr/local/opt/ncurses/include -L/usr/local/opt/ncurses/lib libmenutest.c -o test -lmenu -lncurses
    

    当你最终调用你的程序时,输出如下:

    This worked :^) 
    

    CMake

    对于使用 CMake 的人,您的 CMakeLists.txt 可能如下所示:

    cmake_minimum_required(VERSION 3.14)
    project(libmenutest C)
    
    set(CMAKE_C_STANDARD 99)
    
    include_directories(/usr/local/opt/ncurses/include)
    
    link_directories(/usr/local/opt/ncurses/lib)
    
    add_executable(libmenutest libmenutest.c)
    
    target_link_libraries(libmenutest menu ncurses)
    

    【讨论】:

    • 谢谢!这很有帮助。你知道有没有办法使用 macOS 自带的库?
    • 至少对于当前的 macOS Mojave 来说似乎不是。但不确定早期的操作系统版本。
    【解决方案2】:

    同样的问题。我终于用下面的命令解决了:

    1. 编译成位码

    clang -c -o libmenutest.o libmenutest.c

    1. 没有 -syslibroot 的链接,这是 clang 自动生成的

    ld -demangle -lto_library /Library/Developer/CommandLineTools/usr/lib/libLTO.dylib -no_deduplicate -dynamic -arch x86_64 -platform_version macos 10.15.0 10.15.6 -lSystem /Library/Developer/CommandLineTools/usr/lib/clang/12.0.0/lib/darwin/libclang_rt.osx.a -o a.out libmenutest.o -lmenu -lncurses

    为什么上面的代码有效? ncurses库的默认搜索路径是:

    -lmenu => /usr/lib/libmenu.dylib

    -lncurses => /usr/lib/ncurses.dylib

    使用-syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk,他们变成:

    -lmenu => /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/lib/libmenu.dylib

    -lncurses => /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/lib/ncurses.dylib

    这里是ld 人文档:

    ld 维护目录列表以搜索库或框架 使用。默认库搜索路径是 /usr/lib,然后是 /usr/local/lib。 -L 选项将添加一个新的库搜索路径。默认框架 搜索路径是 /Library/Frameworks 然后是 /System/Library/Frameworks。 (注意:以前,/Network/Library/Frameworks 位于 默认路径。如果您需要该功能,则需要显式添加 -F/网络/库/框架)。 -F 选项将添加一个新框架 搜索路径。 -Z 选项将删除标准搜索路径。这 -syslibroot 选项将为所有搜索路径添加前缀。

    【讨论】:

      猜你喜欢
      • 2018-04-04
      • 1970-01-01
      • 1970-01-01
      • 2020-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      相关资源
      最近更新 更多