常见的在Windows系统中开发Linux C/C++程序的方法,是在Windows系统中安装配置Cygwin或MinGW,构建GCC编译环境,然后在Eclipse/CLion等IDE中配置相应的GCC工具链,以此实现在Windows环境中编译运行Linux C/C++程序。
这种方法可用,但也有很多缺陷:
这些原因都使得Cygwin/MinGW仅适用于一些较轻量级的编程和调试。对于复杂的开源程序,解决编译问题就足以让人焦头烂额。
时代在进步,开发工具也在发展,Win10推出原生Linux子系统,CLion v2018.3开始支持远程开发。这使得在Windows系统中开发Linux C/C++程序有了新的路线。
下面逐一阐述配置CLion和Linux子系统工具链的相关操作,并尽可能提示可能出现的问题及解决方法。
Windows Subsystem for Linux(简称WSL),即Windows环境下的Linux子系统。WSL并非默认启用,请参考《启用Windows10的Linux子系统并安装图形界面》1进行开启。
基本步骤:
连接CLion和Ubuntu子系统需要对Ubuntu子系统进行一些环境配置,比如开启ssh服务(CLion通过SFTP协议完成远程调试)、安装GCC和CMake环境(CLion依赖的编译工具链)。
使用官方源,软件下载和更新会比较慢,可以参考《Linux——Ubuntu 18.04 LTS更换国内apt更新源》2更换国内源。
基本步骤:
sudo mv /etc/apt/sources.list /etc/apt/sources.list.bk
sudo vi /etc/apt/sources.list
复制以下内容到sources.list
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
保存后退出
sudo apt-get update
配置ssh服务参考《windows 下使用Linux子系统》3
基本步骤:
sudo apt-get install openssh-server
备份原ssh配置文件
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bk
修改ssh配置文件
sudo vi /etc/ssh/sshd_config
编辑调整以下 ssh 相关的设置项
Port 8022 # 更换新的端口
ListenAddress 0.0.0.0 # 去掉前面的'#'
UsePrivilegeSeparation no
PermitRootLogin yes
#StrictModes yes # 在前面加上'#'
PasswordAuthentication yes
更换端口号是必要的,因为Linux子系统与Win10系统使用相同的IP地址,默认端口号可能会与Win10系统的ssh服务产生冲突。
生成host key
sudo ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key
生成user key
ssh-keygen -t rsa
sudo /etc/init.d/ssh start
验证ssh服务状态
/etc/init.d/ssh status
确认ssh服务已启动
* sshd is running
如果不设置ssh服务自启动,每次电脑重启后都需要手动启动Linux子系统ssh服务。
常用的Ubuntu设置ssh服务自启动方法,如“sudo update-rc.d ssh enable”、“sudo systemctl enable ssh”、修改“/etc/rc.d/rc.local”等,均不适用于Linux子系统。
可用的方法参考《Win10 wsl linux子系统ssh服务自启动设置》4
sudo apt-get install build-essential
通过“sudo apt-get install cmake”安装的CMake版本较低,可能不满足开发需求,推荐通过源码编译安装。
基本步骤:
到CMake官网选择需要的版本,注意版本不一定选择最新,CLion可能不支持。
wget https://cmake.org/files/v3.14/cmake-3.14.3.tar.gz
依次执行
tar zxvf cmake-3.14.3.tar.gz
cd cmake-3.14.3/
./bootstrap
make
sudo make install
如果有使用Linux子系统图形化界面的需求,可以配置Windows远程桌面连接或Xming,具体请参考《Windows10 Linux子系统安装图形化界面的两种方法及其对比》5
CLion从v2018.3版本才开始全面支持远程开发,详情参见release note,因此需要安装v2018.3或更高版本。配置过程参考《使用Clion优雅的完全远程自动同步和远程调试c++》6
从CLion官网下载Windows版安装包,安装过程不赘述。
因为是远程调试,CLion的工具链就要配置为远程主机的工具链,而Ubuntu子系统就是我们这个案例中的远程主机。
打开CLion的设置界面(File -> Setings),添加一个工具链,环境选择Rmote Host,也可以选择WSL。其实WSL也算是远程主机,并且远程主机的配置能够完全兼容WSL模式。考虑兼容远程主机调试模式,所以下面以远程主机配置方式配置工具链。
点击右侧图标配置登录信息,Host填localhost或127.0.0.1,端口设置为8022(本文2.2节配置的ssh端口号),设置Ubuntu子系统的用户名和密码。
如果登录证书配置成功会显示Connected,将CMake配置为2.4节中安装的cmake命令路径,软件会自动检测Make和C/C++编译器,如果没有检测到可以自行配置。可以给工具链起一个名字保存。
在CMake页面的Environment栏中填入编译时所依赖的环境变量。注意是Ubuntu系统的环境变量(远程编译时无法加载Ubuntu系统的profile和bashrc等文件)。
为什么要设置编译时环境变量?举个例子,在CMakeList.txt中如果使用find_program()查找一个叫“aocl”的程序。
如果该程序不在默认的PATH搜索路径中,则会在加载CMakeList.txt时报错:
此时,就要按照上面的方法,将此程序的路径添加到PATH环境变量中。
跑个题,如果对ssh环境变量问题感兴趣的朋友,可以参考《ssh连接远程主机执行脚本的环境变量问题》7。但可惜的是,CLion通过ssh调用cmake编译时并不会启动bash或sh,因此无法加载bashrc等文件获取环境变量,因此必须在IDE中进行配置。
CLion远程调试的基本原理是将本地工程同步到远程主机,然后使用配置好的远程主机工具链对远程工程进行编译和调试。同时CLion会将远程主机上的依赖头文件同步到本地,以便在本地解析头文件8。默认情况下,CLion将工程同步到/tmp目录下,我们也可以手动配置同步目录( Setings->Deployment)。
在已经配置好远程主机工具链后,同步的连接默认也是配置好的。如果没有配置,可以手动添加一个连接,注意协议选择SFTP。
Mappings页面可以配置映射路径(Deployment path),注意这个路径是一个相对路径,其父目录由Connection页面的“Root path”指定。
至此CLion的远程编译环境就算是配好了。不出意外,就可以正常编译了。
程序编译成功后,运行或调试时可能依赖于某些Ubuntu子系统的环境变量,比如依赖某些动态库(LD_LIBRARY_PATH),或需要调用某些可执行程序(PATH)。基于3.3节中提到的相同原因,我们必须将这些环境变量显式配给CLion。
我们是将CLion安装在Windows系统中的,所以默认情况下,CLion中使用的Terminal就是Windows系统的cmd。如果有需要,我们可以将这个Terminal改为Ubuntu子系统的Terminal。( Setings->Tools->Terminal)
到这里配置就全部完成了~
启用Windows10的Linux子系统并安装图形界面 ↩︎
Linux——Ubuntu 18.04 LTS更换国内apt更新源 ↩︎
windows 下使用Linux子系统 ↩︎
Win10 wsl linux子系统ssh服务自启动设置 ↩︎
Windows10 Linux子系统安装图形化界面的两种方法及其对比 ↩︎
使用Clion优雅的完全远程自动同步和远程调试c++ ↩︎
ssh连接远程主机执行脚本的环境变量问题 ↩︎
Stay local, let your IDE do remote work for you! ↩︎