对多个项目和配置有效使用 Visual Studio 项目属性
我一直使用 Visual Studio 内置的 GUI 支持来配置我的项目,通常使用属性表,以便多个项目将使用通用集。
我对此的主要抱怨之一是管理多个项目、配置和平台。如果您只是使用主 GUI 执行所有操作(右键单击项目 -> 属性),它很快就会变得一团糟,难以维护并且容易出现错误(例如未能正确定义某些宏,或使用错误的运行时库等) 。处理不同的人将依赖库放在不同的位置的事实(例如我的依赖库都位于“C:\Libs\[C,C++]\[lib-name]\”),然后经常管理这些库的不同版本不同的方式(发布、调试、x86、x64 等)也是一个大问题,因为它使在新系统上设置它的时间变得非常复杂,然后存在版本控制和保持每个人的路径分离的问题。 属性表使这变得更好一点,但
我不能让一张表针对不同的配置和平台进行单独的设置(下拉框呈灰色),导致我有很多表,如果以正确的顺序继承,则可以执行我想要的操作。 (“x86”、“x64”、“debug”、“release”、“common”、“directories”(通过定义像 BoostX86LibDir 这样的用户宏来处理前面提到的依赖问题)等)并且如果以错误的顺序继承(例如“x64”和“debug”之前的“common”)会导致诸如尝试链接不正确的库版本或错误地命名输出之类的问题...
我想要的是一种处理所有这些分散的依赖项并设置一个解决方案中我的所有项目使用的一组“规则”,例如将输出库命名为“mylib-[vc90,vc100]-[x86,x64][-d].lib”,而不必执行所有这些操作对于每个单独的项目、配置和平台组合,然后使它们全部正确同步。
我知道要迁移到完全不同的系统,例如 CMake 来创建所需的文件,但这会使其他地方的事情变得复杂,即使是简单的任务(例如向项目添加新文件)也需要在其他地方进行额外的更改,这不是我要做的事情对其中任何一个都非常满意,除非有一些与 VS2010 集成的东西可以跟踪这些类型的变化。
I have always used Visual Studios built in GUI support for configuring my projects, often using property sheets so that several projects will use a common set.
One of my main gripes with this is managing multiple projects, configurations and platforms. If you just do everything with the main GUI (right click the project -> properties) it quickly becomes a mess, difficult to maintain and prone to bugs (like failing to correctly define some macro, or using the wrong runtime library, etc). Dealing with the fact that different people put there dependency libraries in different places (eg mine all live in "C:\Libs\[C,C++]\[lib-name]\") and then often manage the different versions of those libraries differently as well (release, debug, x86, x64, etc) is also a large problem since it vastly complicates the time to set it up on a new system, and then there is issues with version-control and keeping everyone's paths separate...
Property sheets make this a bit better, but I cant have one sheet have separate settings for different configurations and platforms (the drop down boxes a greyed out), resulting in me having many sheets which if inherited in the correct order do what I want ("x86", "x64", "debug", "release", "common", "directories" (deals with the previously mentioned dependency issue by defining user macros like BoostX86LibDir), etc) and if inherited in the wrong order (eg "common" before "x64" and "debug") lead to issues like trying to link an incorrect library version, or incorrectly naming the output...
What I want is a way of dealing with all these scattered dependencies and setting up a set of "rules" which are used by all my projects in the solution, like naming an output library as "mylib-[vc90,vc100]-[x86,x64][-d].lib", without having to do all this for each individual project, configuration and platform combination, and then keep them all correctly in sync.
I am aware of moving to entirely different systems like CMake that create the needed files, however this then complicates things elsewhere by making it so even simple tasks like adding a new file to the project then requires additional changes elsewhere, which is not something I am entirely happy with either, unless there is some with VS2010 integration which can keep track of these sorts of changes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我刚刚发现了一些我认为不可能的事情(GUI 没有公开),这有助于使属性表更加有用。项目属性文件中许多标签的“Condition”属性也可以在 .props 文件中使用!
我只是将以下内容放在一起作为测试,它效果很好,并且完成了 5 个(通用、x64、x86、调试、发布)单独属性表的任务!
唯一的问题是属性 GUI 无法处理它,使用上述属性表的项目仅报告目标的默认继承值,例如“$(ProjectName)”。
I just found out somthing I didnt think was possible (it is not exposed by the GUI) that helps make property sheet far more useful. The "Condition" attribute of many of the tags in the project property files and it can be used in the .props files as well!
I just put together the following as a test and it worked great and did the task of 5 (common,x64,x86,debug,release) separate property sheets!
Only issue is the properties GUI cant handle it, a project that uses the above property sheet just reports default inherited values like "$(ProjectName)" for the target.
我做了一些改进,可能对有人
玩得开心很有用!
I made some improvements, may be useful for somebody
have fun!
我以前对我公司的产品(200多个项目)也有同样的痛苦。我解决这个问题的方法是建立一个很好的属性表层次结构。
项目通过其输出类型继承属性表,例如 x64.Debug.Dynamic.Library.vsprops。这个 vsprops 文件只是使用 InheritedPropertySheets 属性继承其他属性表。
您还可以在属性表中使用变量(即 UserMacro,其值可以是绝对变量甚至环境变量)来根据您的需要自定义很多内容。例如,在 Debug.vsprops 中定义一个 BIN 变量,
然后当您在一系列 vsprops 中设置输出名称时,例如 Output.x64.Library.vsprops,
$(BIN) 变量将扩展为已设置的内容(在本例中) , 调试)。使用这种技术,您可以轻松构建良好的属性表层次结构来满足您的需求。
现在您可能还想做一件事:构建您自己的使用属性表集的项目模板。真正困难的部分是强制正确使用模板和属性表。我个人的经验是,即使一切都设置好了,有人仍然会忘记使用模板来创建新项目......
I had same pain for the product of my company (200+ projects) before. The way I solved it is to build a nice hierarchy of the property sheets.
The projects inherits the property sheet by its output type, say x64.Debug.Dynamic.Library.vsprops. This vsprops file simply inherits other property sheets using the InheritedPropertySheets attribute
You can also use variables (i.e. UserMacro, whose value can be absolute or even environment variables) in property sheets to customize a lot of things based on your need. For example, defining a BIN variable in Debug.vsprops
then when you set the output name in the series of vsprops, say, Output.x64.Library.vsprops
The $(BIN) variable will be expanded to what's been set (in this case, Debug). Use this technique you can easily construct a nice hierarchy of property sheets to meet your demand.
Now there's one more thing you might want to do: build your own project templates that uses your property sheet set. The real difficult part is to enforce proper usage of the templates and property sheets. My personal experience is that even if everything is setup, somebody will still forget to use the template to create new projects ...
可以为每个配置创建单独的属性表。要执行此操作:
这可以缓解您无需将条件插入到单个工作表中以进行多种配置。如果您希望在配置之间共享一些通用属性,请创建层次结构。顶部工作表可用于所有配置,嵌套工作表将仅包含特定于配置的属性
It is possible to create a separate property sheet for each configuration. To do this:
This relieves you from inserting conditions into a single sheet for multiple configurations. If you have some common attributes that you would like to share between configurations, then create a hierarchy. The top sheet can be used in all configurations and the nested sheets will only contain the configuration-specific attribut
就输出库而言,您可以选择所有项目,然后打开属性页,选择所有配置、所有平台,然后将目标名称设置为:
$(ProjectName)-$(PlatformToolset)-$ (PlatformShortName)-$(Configuration)
会给出类似 mylib-v100-x86-Debug.lib 的输出
我们也使用
$(PlatformName) 和
#(Configuration)
来选择正确的库路径,尽管这确实意味着对库的初始设置进行一些混乱。例如,我们将 boost 安装其库到boost/lib.Win32
或boost/lib.x64
。关于库以及将它们安装在不同地方的人们,有几种选择。如果您有一个非常强大的源代码管理系统,您可以将所有内容都放在源代码管理中,位于源代码旁边的 libs 文件夹中。如果您使用多个库,或者它们特别大,那么这可能不起作用。
我想到的另一个选项是在每个用户计算机上设置一个环境变量,指向其库文件夹的根目录,例如
LIB_ROOT=c:\libraries
,然后您可以在 Visual 中访问它工作室为$(LIB_ROOT)
。As far as the output library goes, you can select all your projects, then bring up the property pages, select All Configurations, All Platforms and then set the Target Name to:
$(ProjectName)-$(PlatformToolset)-$(PlatformShortName)-$(Configuration)
which would give an output like mylib-v100-x86-Debug.lib
We do something similar to this for Additional Library Directories as well, using
$(PlatformName)
and#(Configuration)
to pick out the right library paths, although it does mean some messing around with initial setup of the libraries. eg we have boost install its libs toboost/lib.Win32
orboost/lib.x64
.With regards to libraries, and people installing them in different places, there are a couple of options. If you have a very robust source control system, you can just put everything in source control, living in a libs folder next to your source. That probably won't work if you use more than a few libraries though, or if they are particularly large.
The other option that comes to mind is to set an environment variable on each user machine that points to the root of their libraries folder, eg
LIB_ROOT=c:\libraries
, and you can then access that in Visual Studio as$(LIB_ROOT)
.如果您想定义一些对整个解决方案有效的 UserMacros:
在解决方案根文件夹中创建一个
solution-global.props
文件在其中定义您的 UserMacros:
在您想要使用自定义宏的每个
*.vcxproj
文件中插入以下行:<导入项目="$(SolutionDir)solution-global.props"/>
使用您的自定义宏:
适用于 VS2015
If you want to define some UserMacros which should be valid for the entire solution:
Create a
solution-global.props
file in your solution root folderDefine there your UserMacros:
insert in each
*.vcxproj
file in which you want to use your custom macros this line:<Import Project="$(SolutionDir)solution-global.props" />
Use your custom macro:
<AdditionalIncludeDirectories>$(CommonUtilsDir)\Source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
Works in VS2015
听起来似乎值得检查一个构建工具 - 在我的地方,我们使用一个定制的工具来监视文件和项目的更改并计算依赖关系和编译顺序。添加新文件没什么大不了的 - 编译是通过 msbuild 完成的。
如果我必须编译多个项目,我会使用类似 nant 的东西:
http://nant.sourceforge.net/
It sounds like it could be worth checking out a build tool - at my place we use a custom made tool that watches files and projects for changes and figures the dependencies and compile order. Adding a new file is no big deal - compilation is done with msbuild.
If i had to compile more than a bunch of projects I would use something like nant:
http://nant.sourceforge.net/