Xcode和Curses.h,错误打开终端

arc*_*eoi 7 curses macos terminal xcode gcc

我正在尝试用Xcode编译一个简单的诅咒项目.
该程序使用标志-lcurses在终端中使用g ++进行编译,运行正常.

通过创建类型为c ++的命令行工具开始.
导入curses.h进入我的主要.
在Tar​​get"program"Info - > General - > Linked Libraries中,添加了libCurses.dylib.

它编译得很好,但终端窗口不会打开.
在调试控制台中,输出是,

程序已加载.
运行
[切换到进程3424]
打开终端时出错:未知.
正在运行...

我可以去构建文件夹,只是在终端打开程序,但有没有办法让xcode打开终端?

谢谢你的帮助!

C0D*_*F52 9

我在Xcode中使用ncurses调试时遇到了同样的问题.最后,我找到了一个很好的方法来管理使用Terminal.app进行调试,允许调试ncurses.

我们知道,要初始化和使用ncurses,我们需要在终端中运行我们的应用程序.但是当我们按下运行按钮时,Xcode没有打开终端.因此,如果我们从代码中请求环境变量TERM,我们将获得NULL.这就是应用程序在initscr()上崩溃的原因.

但Xcode允许我们为运行方案(产品>方案>编辑方案...>运行)设置启动选项为"等待可执行文件启动"而不是默认"自动": 更改运行方案的启动选项

现在我们可以在Xcode中按Run,并在终端中手动启动我们的应用程序.因此调试器将附加到应用程序.有两个问题:

  1. 如果诚实地说,调试器不会在没有其他操作的情况下自我附加,它将跳过所有断点.但是我们可以通过在程序开始时调用getchar()来管理它.我通过引入指示我们在终端中调试的命令行参数解决了这个问题:

    for (int argi = 1; argi < argc; argi++)
    {
        if (strcmp(argv[argi], "--debug-in-terminal") == 0)
        {
            printf("Debugging in terminal enabled\n");
            getchar(); // Without this call debugging will be skipped
            break;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    因此,只有当我们想在Terminal.app中调试时,我们才能打开getchar()调用

  2. 我们需要打开终端并在每次按Xcode中的Run时手动启动应用程序.这真的很烦人.所以,我决定通过运行方案设置中的预操作来自动化它.我们的想法是打开终端并在其中运行我们的应用程序.但是这个预先动作应该启动应用程序,然后Xcode将执行Run动作,让它首先"等待可执行文件启动".所以我们需要一个延迟的后台非阻塞任务.这可以通过以下shell命令(&最终需要在后台运行)来实现:

    osascript -e 'tell application "Terminal"' -e 'delay 0.5' -e "set currentTab to do script (\"$TARGET_BUILD_DIR/$PRODUCT_NAME --debug-in-terminal\")" -e 'end tell' &
    
    Run Code Online (Sandbox Code Playgroud)

    不要忘记在"提供构建设置"列表中选择您的应用程序,以使可访问的重要环境变量$ TARGET_BUILD_DIR和$ PRODUCT_NAME: 提供构建设置

    所以,现在当我们按Run时,Xcode将等待可执行文件附加,终端将被打开,我们的应用程序将使用命令行选项--debug-in-terminal执行,所有断点都将被触发.

    非常好,但最终关闭此终端窗口会更好,因为它会为每个调试会话生成一个新窗口.让我们在Post-actions for Run方案中做到:

    osascript -e 'activate application "Terminal"' -e 'delay 0.5' -e 'tell application "System Events"' -e 'tell process "Terminal"' -e 'keystroke "w" using {command down}' -e 'end tell' -e 'end tell'
    
    Run Code Online (Sandbox Code Playgroud)

    在此输入图像描述

    此命令只关闭活动终端窗口,因此如果您计划在调试会话期间将某个终端用于其他目的,则可能不需要此Post-action,因为您可能会意外关闭某个重要窗口.

最后,一个安全ncurses代码的想法,检查我们是否可以使用ncurses或不:

#include <stdlib.h>
#include <string.h>
#include <ncurses.h>


bool IsTerminalAvailable = false; // Check this global variable before ncurses calls


int main(int argc, const char *argv[])
{
    for (int argi = 1; argi < argc; argi++)
    {
        if (strcmp(argv[argi], "--debug-in-terminal") == 0)
        {
            printf("Debugging in terminal enabled\n");
            getchar(); // Without this call debugging will be skipped
            break;
        }
    }

    char *term = getenv("TERM");

    IsTerminalAvailable = (term != NULL);

    if (IsTerminalAvailable)
        IsTerminalAvailable = (initscr() != NULL);

    // Do some code here....

    if (IsTerminalAvailable)
    {
        printw("Press any key to exit...");
        refresh();

        getch();

        endwin();
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*ull 6

在 XCode 8 中,您可以从“编辑方案...选项”页面选择在终端内运行。 XCode 8 截图

尽管在我的快速测试中,它似乎并没有那么好用;有时(并非总是)它似乎“丢失”了被调试者,或者被调试者从未启动,并认为它仍在运行。如果您尝试退出,Xcode 就会卡住。我发现,如果您找到并杀死一个名为的进程,lldb-rpc-server则可以避免强制退出。

更详细地说(如果这对任何人都有帮助)每当调试程序无法启动时,我打开一个终端并输入

ps x | grep lldb
Run Code Online (Sandbox Code Playgroud)

然后

kill 12345
Run Code Online (Sandbox Code Playgroud)

12345ps 给我的进程 ID 在哪里。


小智 4

Xcode IDE 中没有可连接的终端。而是从 shell 运行程序(通过终端应用程序)

./build/Debug/myprogram
Run Code Online (Sandbox Code Playgroud)

如果您想使用 IDE 调试器(即 gdb),您可以附加到该进程。首先获取进程ID,

gdb> attach mypid
Run Code Online (Sandbox Code Playgroud)

为了更方便的方法,我将引用Step into Xcode: Mac OS Xdevelopment

打开“组和文件”列表中的“可执行文件”组 ,选择应用程序,打开“信息”窗口,然后在“调试”选项卡中取消选中“启动调试器后启动可执行文件”。当您准备好调试时,启动调试器,然后在其友好的环境中启动目标应用程序。在调试器的 gdb 控制台中,输入Attach myprogram,调试会话正在进行。