netbeans 8.0远程调试linux C++工程记

大家都知道的就不说了,目前的环境,代码和build/run环境都在linux server上,netbeans在我工作机win7上,我通过sftp的模式来直接创建netbeans工程并远程开发。

问题就在调试上,这个工程依赖极多的第三方库,并且需要很多环境变量才能运行(例如JNI调用需要的CLASSPATH等),所以我们专门有一个dev-config.sh脚本来初始化build和run的环境(探测和生成需要的环境变量)。

build的环境好说,我们通过一个build.sh来简单封装了dev-configure.sh和cmake的调用,这样生成的Makefile就不再依赖那些环境变量,netbeans可以直接通过Makefile来build工程。

而运行和调试的时候,netbeans(7.4)只能填写一个elf的目标文件(和命令行参数)来启动进程,这样我们的startup.sh脚本(封装了dev-config.sh和elf目标文件的调用)根本派不上用场;虽然可以在工程设置里面添加环境变量,我们的环境变量的数量和变化频率让这个工作变得有点惊悚。

 

失败的尝试

于是我想,干脆让netbeans到linux server的ssh会话自动设置好dev-config.sh,这需要两步:

首先在/etc/ssh/sshd_config中这样设置

Match User nbdev
       ForceCommand /home/nbdev/.ssh/devEnvLoader.sh

 这样netbeans用来创建ssh会话的用户nbdev只要一连接(除非ssh -N这种情况,但是这里出现不了)就会转而执行指定的devEnvLoader.sh脚本。

然后这个脚本是这么编写的,用来实现在原始的ssh命令之前挂上我们的dev-config.sh:

#!/bin/sh

if [ -n "$SSH_ORIGINAL_COMMAND" ]; then
        . /mnt/IanCurtis/codebase/dev-config.sh > /dev/null 2>&1
        # have to use perl to achive the effect which should be written as "exec eval $SSH_ORIGINAL_COMMAND"
        exec perl -e 'exec $ENV{SSH_ORIGINAL_COMMAND}'
else
        # start a normal login shell
        exec /usr/bin/bash --login
fi

 其中想用exec来运行原来的ssh命令替掉当前sh进程,但是有时候那个环境变量解开后是字符串,没法用exec,只好用perl来处理。shell这门“语言”实在是太反人类了。

经过自己的测试,无论是ssh nbdev@linuxserver,还是ssh nbdev@linuxserver sh -s,还是sftp nbdev@linuxserver之类的会话,都成功地初始化了开发环境。

 

但是不好用。

。。。

 

只好在上面的脚本里面加log,看看netbeans干了什么,于是有了下面的方案。

 

成功的hack

netbeans在/var/tmp/dlight_nbdev下生成了一些每个工程对应的“环境和工具”,例如我这个工程就是/var/tmp/dlight_nbdev/418800f2,里面有一个env文件,所有的build和debug都是用的这个文件,用strings env查看后发现这个文件并没有开发环境那些环境变量,所以导致debug无法启动。

这个文件我可以肯定是用的/var/tmp/dlight_nbdev/418800f2/0457354793/pty --dumpenv env这个命令来生成的,但是我不知道既然netbeans肯定是通过ssh会话来运行这个命令,为毛生成的env里面却没有开发环境的配置,至今也不知道。

所以就有了一个直接的hack,首先自己source dev-config.sh,让当前的shell具备开发环境的配置,再运行上面的命令重新生成一个env应该就可以了。

 

的确可以,但是新产生的一个问题就是要防止netbeans重新生成这个文件,经过测试(nb8.0):

netbeans在删除工程的时候才会删掉/var/tmp/dlight_nbdev下面的相应目录;

netbeans打开了工程,关闭netbeans,修改env,重开netbeans,又被改回去了;

netbeans中打开了工程,关闭该工程,修改env,重开该工程,没有覆盖刚修改的env;

当修改后的env一旦被netbeans接受,那么重启netbeans什么的,都不会覆盖刚修改的env。

所以就用第三种的情况的方法来操作,成功率比较高。

 另外我也把env中的LANG设置为en_US.UTF-8,因为当build出的output中有中文字符的话,netbeans的output窗口中的编译错误无法变成可以点击的链接,这个方法可以很大概率上回避这个问题。

你可能感兴趣的:(Netbeans)