辛亚平的博客专栏

Visual C++ for Linux Tips (01): `Copy File` 失效的解决方案

Visual C++ for Linux Tips (01): Copy File 失效的解决方案

01.问题描述

通过 MSVC 的 Visual C++ for Linux 开发 Linux 应用程序非常方便,但是它总有一些小问题。我从 Visual C++ for Linux 推出第一个版本开始起就尝试着用它,见证了每一个新版本都解决了旧版本的一些问题,到现在已经变得越来越完善了,但还是有一些长期存在的问题有待解决。

借着手头写一个新的工具软件的机会,说一下Copy File 失效的问题。

开发 Windows 程序时,Copy File的表现

为了说明Copy File这个 feature 在 Visual C++ for Linux 上存在的问题,我们先对比一下,开发 Windows 程序时,Copy File的正常表现。

比如说,如下图所示,我项目中引用了一个配置文件:TelemDecoder_logsconf_kvfile.conf,我希望每次我的程序编译之后,配置文件被自动拷贝到编译输出目录的Resource/Configuration子目录中,如果该子目录不存在,则创建该子目录再拷贝。
image

我们在TelemDecoder_logsconf_kvfile.conf这一项上面单击鼠标右键,在 Context Menu (右键菜单)中设置它的属性:
image
Content 属性选择Yes,表明这个文件是和程序编译过程有关的。Item Type 属性选择Copy File,这时,左边的配置属性列表中就会多出来Copy File这个类别。
如下图所示,在Copy File这个属性类别中,我们可以在Destination Directories属性中设置文件输出的路径。此处我们将该路径设置为:$(OutDir)/Resource/Configuration
image
这样,在程序编译完后,在编译结果输出目录中,可以看到,(1) Resource/Configuration子目录被创建;(2) TelemDecoder_logsconf_kvfile.conf文件被拷贝到了该子目录中。
image

image

开发 Linux 程序时,Copy File的表现

然而,在用 Visual C++ for Linux 插件开发 Linux 程序时,我们也将TelemDecoder_logsconf_kvfile.conf配置文件设置成:Content: Yes; Item Type: Copy File,并按照我们之前的理解设置了Copy File这个属性类中的Destination Directories属性,结果,TelemDecoder_logsconf_kvfile.conf并未被拷贝到我们期望的目录。岂止是这样,当我们查看都有哪些文件被上传到了 Remote Machine,结果发现TelemDecoder_logsconf_kvfile.conf并没有像源代码文件那样被上传到 Remote Machine。

02.问题检索

要相信,如果我们遇到的这个问题不是特别冷门,在互联网上应该也有许多人遇到了同样的问题。看看他们都有哪些讨论。
经过搜索,发现果然有很多同行在讨论这个问题,但是迄今为止还没有什么特别好的解决办法。

检索结果一:Files not being copied remotely #369

Files not being copied remotely #369 这个链接中,我们看到,早在2019年3月,就有人在 https://github.com/Microsoft/VSLinux/ 这个开源项目中报告过这个 Bug。是的,这当然是一个显而易见的 Bug。不过这个 Bug 拖到了现在还没有解决,现在已经是2022年12月了,我的 Visual Studio 2022 的版本也已经升级到了最新的 17.4.2,该 Bug 依然可被复现。

检索结果二:丑陋的 Workaround

典型的讨论,见:Visual C++ for Linux: copy content files to build directory? 这是 Stackoverflow 上的讨论。通常来说, Stackoverflow 里面的回答者还是比较有耐心的。

目前从互联网上检索到的变通的解决办法( Workaround),无非是有 2 个:一个办法就是在 Post-Build Event 中进行文件拷贝;另一个办法就是在项目属性中的 Copy Sources 属性类中,配置Additional Sources To Copy

Visual C++ for Linux 的 Post-Build Event 一直都用得有点别扭,我曾经在这个地方折腾过很多次。不太指望在这里进行稍微复杂一点的设置。
Additional Sources To Copy详见链接:Copy Sources Project Properties (Linux C++) 我实在是不想用这个办法,因为它要设置 fulllocalpath 和 fullremotepath,这令我非常抗拒。我本来就希望项目设置尽可能灵活适应不同的开发者/开发环境,一旦用上了 fullpath,每次都得告诉其他人将此处改成他们自己的开发环境所采用的路径。我希望这里能够采用相对路径,然后用上像$(OutDir)这样的IDE变量,但是经过一圈折腾,发现相对路径行不通。

总之上面说的这两个解决办法都非常丑陋。

03.解决办法

首先,解决文件被上传到 Remote Machine 的问题首先,解决文件被上传到 Remote Machine 的问题

首先我希望TelemDecoder_logsconf_kvfile.conf这个配置文件能够像源代码文件那样被自动上传到 Remote Machine 中去,这样的话,我哪怕是通过一些笨办法,也能实现自动部署到我期望的目录中去这个想法。

经过尝试,我发现比较理想的做法,是将该文件的属性设置为:Content: Yes; Item Type: Text,如下图所示:
image

然后 Build,发现好歹TelemDecoder_logsconf_kvfile.conf能够被部署到源代码文件中去了。这就有戏。

设置文件部署路径:重命名Remote File

在 Copy Sources 属性类中,可以通过Remote File来设置文件部署的位置和名称。

看看我们能够借助的IDE环境变量有哪些:如下图所示,$(RemoteOutDir)这个变量正合我意。
image

所以,我们把Remote File设置为:$(RemoteOutDir)/Resource/Configuration/TelemDecoder_logsconf_kvfile.conf,如下图所示:
image

Copy Sources 属性类的设置如下表所示:

Property Value
Remote File $(RemoteOutDir)/Resource/Configuration/TelemDecoder_logsconf_kvfile.conf
Copy Remotely Yes
Copy To Output Directory No

然后执行 Build,结果正如我们预期的那样。问题解决。

(幸亏通过设置Remote File属性解决了这个问题,否则我就只能通过 Shell 脚本来进行文件部署了。)

posted on 2022-12-01 22:57  辛亚平  阅读(202)  评论(0编辑  收藏  举报

导航