Xcode和Curses.h错误打开终端 [英] Xcode and Curses.h with Error opening terminal

查看:441
本文介绍了Xcode和Curses.h错误打开终端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我想用Xcode编译一个简单的curse项目。

程序在终端中用g ++编译得很好,运行良好。



通过创建类型为c ++的命令行工具开始创建。
将curses.h导入到我的主目录中。

在目标程序信息 - >常规 - >链接库中,添加了libCurses.dylib。


编译正常,但终端窗口不会打开。
在Debug Console中,输出是

程序已加载。

run
[切换到进程3424]

错误

正在运行...


我可以去建立文件夹并在终端打开程序,但是在那里任何方式为xcode打开终端?



感谢您的任何帮助!

解决方案

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



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



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



现在我们可以按下Xcode中的Run,然后在Terminal中手动启动我们的应用程序。所以调试器将被附加到应用程序中。这里有两个问题:


  1. 如果说实话,调试器不会被自动附加而没有额外的动作,它会跳过所有断点。但是我们可以通过在程序开始时调用getchar()来进行管理。我通过引入命令行参数来解决这个问题,该命令行参数表明我们正在调试终端:

      for(int argi = 1; argi< ; argc; argi ++)
    {
    if(strcmp(argv [argi],--debug-in-terminal)== 0)
    {
    printf(Debugging在终端启用\ n);
    getchar(); //没有这个调用,调试将被跳过
    break;






    $ b所以我们可以只打开getchar()当我们想在Terminal.app里面进行调试时,我们需要打开终端并在每次按下Xcode中的Run时手动启动应用程序。这真的很烦人。因此,我决定通过运行方案设置中的预先操作来自动化它。这个想法是打开终端并运行我们的应用程序。但是,此预执行应启动应用程序后,Xcode将执行运行操作,让它首先等待可执行文件启动。所以我们需要一个延迟的背景无阻塞任务。这可以通过以下shell命令来实现(&最后需要在后台运行):

      osascript -e'告诉应用程序Terminal'-e'delay 0.5'-eset currentTab to do script(\$ TARGET_BUILD_DIR / $ PRODUCT_NAME --debug-in-terminal \)-e'end tell'& 

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

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



    相当不错,但是最后关闭终端窗口会更好,因为它会为每个调试会话生成一个新窗口。让我们在Post-action for Run方案中做到这一点:

      osascript -e'激活应用程序Terminal'-e'delay 0.5 '-e'告诉应用程序系统事件'-e'告诉过程'终端''-e'使用{command down}'-e'结尾告诉'-e'结束告诉'



    此命令仅关闭活动终端窗口,因此如果您打算在调试会话期间将终端用于其他用途,则可能不需要此后操作,因为您可以意外关闭某个重要窗口。


最后,一个安全的ncurses代码的概念,检查我们是否可以使用ncurses或no:

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


bool IsTerminalAvailable = false; //在ncurses调用


之前检查这个全局变量int main(int argc,const char * argv [])
{
for(int argi = 1; argi {
if(strcmp(argv [argi],--debug-in-terminal)== 0)
{
printf( 在终端启用\ n调试);
getchar(); //没有这个调用,调试将被跳过
break;



char * term = getenv(TERM);

IsTerminalAvailable =(term!= NULL);

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

//在这里做一些代码....

if(IsTerminalAvailable)
{
printw(按任意键退出... );
refresh();

getch();

endwin();
}

返回0;
}


I am trying to compile a simple curse project with Xcode.
The program compiles fine with g++ in terminal with the flag -lcurses, and runs fine.

Started of by creating a Command Line Tool with type c++.
imported curses.h into my main.
In the Target"program"Info -> General -> Linked Libraries, libCurses.dylib has been added.

It compiles fine but the terminal window will not open.
In the Debug Console the output is,

Program loaded.
run
[Switching to process 3424]
Error opening terminal: unknown.
Running…

I can go to build folder and just open the program in terminal but is there any way for xcode to open the terminal?

Thanks for any help!

解决方案

I had the same problem with ncurses debugging in Xcode. Finally I've found a good way for me to manage debugging with Terminal.app that allows to debug ncurses.

As we know, to initialise and use ncurses we need to run our application in terminal. But Xcode doesn't open terminal when we press run button. So, if we request environment variable TERM in from code, we'll get NULL. This is why application crashes on initscr().

But Xcode allows us to setup Launch option for Run scheme (Product > Scheme > Edit scheme... > Run) to "Wait for executable to be launched" instead of default "Automatically":

Now we can press Run in Xcode and after launch our application manually in Terminal. So debugger will be attached to the application. There are 2 problems in that:

  1. If say honestly, debugger will not be attached self without additional actions and it will skip all breakpoints. But we can manage it by calling getchar() at the beginning of our program. I solved this problem by introducing command line argument that indicates we are debugging in terminal:

    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;
        }
    }
    

    So, we can turn on getchar() call only when we want to debug inside Terminal.app

  2. We need to open Terminal and launch the application manually each time when we press Run in Xcode. This is really annoying. So, I decided to automate it through Pre-actions in Run scheme settings. The idea is to open Terminal and run our application in it. But this pre-action should launch the application AFTER Xcode will execute Run action to let it "Wait for executable to be launched" first. So we need a background non-blocking task with a delay. This can be achieved by following shell command (& in the end needed to run in the background):

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

    Don't forget to select your application in "Provide build settings from" list to make accessible important environment variables $TARGET_BUILD_DIR and $PRODUCT_NAME:

    So, now when we press Run, Xcode will wait for executable to attach, Terminal will be opened and our application will be executed with command line option --debug-in-terminal and all breakpoints will be triggered.

    Pretty nice, but it will be even better to close this Terminal window in the end, because it will generate new one for each debug session. Let's do it in Post-actions for Run scheme:

    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'
    

    This command just closes active terminal window, so maybe this Post-action is not needed if you plan to use terminal for some other purposes during debug session, because you can close some important window accidentally.

And finally, an idea of safe ncurses code, that checks if we can use ncurses or no:

#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;
}

这篇关于Xcode和Curses.h错误打开终端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆