Visual Studio 2010项目文件过滤器

4
我正在处理一组复杂的C/C++应用程序,这些应用程序应该是跨平台的。目前为止,它可以在UNIX/Windows上兼容并且运行良好。然而,使用VS2010来维护这个庞然大物是一场噩梦。我有以下的文件结构:
/sources /lib1 /include ... /src ... /lib2 /include ... /src ... /app3 /include ... /src ... /builders /cmake ... /make ... /VS2010 /vs2010.sln /lib1 /lib1.vcxproj /lib1.vcxproj.filters /lib2 /lib2.vcxproj /lib2.vcxproj.filters /app3 /app3.vcxproj /app3.vcxproj.filters
正如我们所看到的,因为所有的内容都是跨平台的,我不得不完全将builders与sources分开。在我看来,这本身就是一个非常好的做法,应该被每个人强制执行。
现在问题来了... VS2010 在组织包含/源文件时变得完全无法使用。你必须手动重复执行“添加 -> 新建筛选器”后面跟着“添加 -> 现有项”。我的文件夹结构非常复杂,每个include文件夹中都有文件。创建筛选器的任务变成了一整天的工作。另一方面,我可以将整个文件夹从资源管理器拖动到VS2010项目中,但是它会将所有头/源文件放在里面,没有任何筛选器,这使得它毫无价值:你不可能在100个文件中寻找正确的文件而没有某种层次结构。
问题是: 是否有一种模糊的方式可以在VS2010中导入文件夹并保留文件夹结构作为筛选器?看起来像是Microsoft创建VS2010的人认为Microsoft是丛林中唯一的动物,你必须在sources文件夹中添加builders项目,以便你可以利用“显示隐藏文件”将它们包含在项目中,并与文件夹结构一起使用。在我看来,这简直是荒谬的...

3
如果你使用CMake,为什么还要维护VS2010项目文件呢?请更加中立,停止使用"M$"这样的用语。 - Synxis
你可以编写一个一行脚本来生成.filters文件的相关部分。可以在Linux或Cygwin下运行它,也可以编写.ps1.bat文件。 - Notinlist
@Synxix:你说得对。我道歉。我只是在发泄...我必须保留VS2010,因为我喜欢多样性。负责Windows维护的我的团队其他成员想使用VS2010,因为他们觉得在其中很有生产力(或者他们以为到现在为止...)。 - shiretu
我并不反对使用VS2010(例如我自己也在使用),但我认为你应该只使用CMake。使用CMake可以生成VS2010项目文件(以及makefile文件)。这非常容易实现,甚至可以编写一个小的*.bat脚本来调用CMake(如果开发人员非常懒的话 ;) )。 - Synxis
@Synxis:是的,我知道cmake,它是我最喜欢的构建工具之一。我也用它来进行嵌入式构建。虽然我从未测试过它生成sln/vcxproj文件,但我会尝试一下。但是,如果生成的VS2010项目只能由编译器读取(所有文件都在同一个筛选器下),那么对于编码来说就毫无价值了。程序员最好使用其他东西,比如NetBeans。让人们从他们喜欢的IDE转换很难,所以我想我应该让他们的生活更轻松。因此,我执着于找到解决筛选问题的方法。 - shiretu
显示剩余2条评论
1个回答

8
您正在使用 CMake,我建议您坚持使用它。您可以使用它生成 make 文件和 VS2010 项目文件(至少如此)。对于 VS,生成的文件是一个 sln 文件和一堆 vxproj 文件(在 CMake 脚本中每个项目都有一个)。
在 CMake 文件中,您可以使用 source_group 命令分组文件。根据源组生成的筛选器将自动为 vs 生成。我不知道其他 IDE,例如 Code::Blocks 或 NetBeans。
如果您想要基于文件路径进行自动分组 [请求评论]
# Glob all sources file inside directory ${DIRECTORY}
file(GLOB_RECURSE TMP_FILES
    ${DIRECTORY}/*.h
    ${DIRECTORY}/*.cpp
    ${DIRECTORY}/*.c
)

foreach(f ${TMP_FILES})
    # Get the path of the file relative to ${DIRECTORY},
    # then alter it (not compulsory)
    file(RELATIVE_PATH SRCGR ${DIRECTORY} ${f})
    set(SRCGR "Something/${SRCGR}")

    # Extract the folder, ie remove the filename part
    string(REGEX REPLACE "(.*)(/[^/]*)$" "\\1" SRCGR ${SRCGR})

    # Source_group expects \\ (double antislash), not / (slash)
    string(REPLACE / \\ SRCGR ${SRCGR})
    source_group("${SRCGR}" FILES ${f})
endforeach()

谢谢您的建议。我会尽快尝试源代码组合技巧,并回来报告结果。 - shiretu
我接受了建议,将其作为一个好答案,因为理论上你可以这样做并使用所有这些过滤器。但是,仍然需要大量的工作来对它们进行分组。例如,对于 cmake 中的 glob-ing,我会在 *.c 和 *.cpp 上进行。对于头文件,我只需将相关项目中的 /include 添加到 INCLUDE_DIRECTORIES 中。在我的看法中,即使使用了 cmake,分组仍然是一个艰巨的手动任务。此外,cmake 生成的工作 sln 非常混乱,不干净。我希望 VS 有像“从文件夹添加现有项”这样的功能。NetBeans 有它,eclipse 也有,但没有 VS ... - shiretu
1
为了完整起见,人们可能会想知道为什么我在拥有cmake的情况下还保留“make”。因为并非所有平台都支持cmake。例如,在solaris上,安装cmake是一次真正的冒险。看起来cmake并不那么跨平台。这就是为什么要遵循我的建议:始终将构建器与源代码完全解耦。 - shiretu
1
@Synxis,您是否有一个使用“foreach”和“glob操作”来遵循目录结构的源组的简短示例?对于像我这样刚接触 CMake 的人来说,找出最简单的东西需要花费数小时的时间。 - sehe
@sehe 我编辑了我的帖子,那应该回答了你的问题。如果有帮助到你,请随意点赞 ;) - Synxis
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接