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

时间:2011-02-07 08:46:09

标签: xcode macos gcc terminal curses

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

通过创建类型为c ++的命令行工具开始 将curses.h导入我的主体。
在Tar​​get“程序”信息中 - >一般 - >已添加链接库libCurses.dylib。

编译正常但终端窗口无法打开 在调试控制台中,输出为

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

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

感谢您的帮助!

4 个答案:

答案 0 :(得分:9)

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

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

但Xcode允许我们为运行方案设置启动选项(产品>方案>编辑方案...>运行)到"等待可执行文件启动"而不是默认"自动": Changing Launch option for Run scheme

现在我们可以在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;
        }
    }
    

    所以,我们只有在想要在Terminal.app内调试时才能打开getchar()调用

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

    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' &
    

    请勿忘记在&#34;中提供构建设置&#34;列表以使可访问的重要环境变量$ TARGET_BUILD_DIR和$ PRODUCT_NAME: Provide build settings from

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

    非常好,但最后关闭此终端窗口会更好,因为它会为每个调试会话生成一个新窗口。让我们在Run-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'
    

    enter image description here

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

  3. 最后,安全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;
    }
    

答案 1 :(得分:4)

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

./build/Debug/myprogram

如果要使用IDE调试器(只是gdb),可以附加 到这个过程。拳头获取进程ID,

gdb> attach mypid

为了更方便的方法,我将引用步入Xcode:Mac OS X开发

  

打开中的可执行文件组   群组&amp;文件列表,选择应用程序,打开信息窗口,然后   在Debugging选项卡中,取消选中 Start   启动调试器后可执行文件。   当您准备好调试时,启动   调试器,然后启动   友好的目标应用   环境。在调试器的gdb中   控制台,键入附加myprogram ,和   你的调试工作正在进行中。

答案 2 :(得分:2)

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

虽然在我的快速测试中,它看起来似乎没有那么好用;它有时(并不总是)似乎“丢失”调试对象,或者调试对象永远不会启动,并认为它仍在运行。如果你试图退出,Xcode会卡住。我发现,如果你发现然后杀死一个名为lldb-rpc-server的进程,你可以避免强行退出。

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

ps x | grep lldb

然后

kill 12345

其中12345是ps给我的进程ID。

答案 3 :(得分:0)

按照Peter Hull的回答,在Scheme-> Run-> Options中也选择“ Console-Use Terminal”对我也有用。

关于无法正常退出的lldb-rpc服务器:只需将以下内容添加到“产品”->“方案”->“编辑方案”->“运行”->“后动作”中

ps -ef |grep lldb-rpc-server |grep -v grep | awk '{print $2}' | sort -rn | while read PID ; do kill $PID ; done

这将找到lldb-rpc-server进程,该进程应归您的用户标识所有,以相反的顺序对其进行排序,然后简单地对其进行分派。

Xcode-Run-PostAction-kill-lldb-rpc-server

这对我很有帮助!我希望它也能帮助其他人!

-TechnoPak