☰
Vivado复制工程报错Common 17-1294 Unable to create directory的排查与解决
2026/10/1 1:40:41 网站建设 项目流程

1. 这个问题是怎么冒出来的

先说说我自己的经历。上个月我做完一个带千兆网口和DDR3的工程,综合实现跑完、板上也验证过一轮,想把这套逻辑复制一份当模板,给另一个项目复用。我直接在文件管理器里把整个工程文件夹选中、复制、粘贴,改了新名字,然后双击新目录下的 .xpr 打开。Vivado 界面倒是正常弹出来了,工程结构看着也完好,可我刚要点 Run Synthesis,进度条还没走两步,底部 Console 就甩出一行红字:

[Common 17-1294] Unable to create directory 'C:/Users/xxx/Desktop/project_copy/project_copy.runs/synth_1'

我当时的第一反应是:目录不是就在那儿吗?我复制的时候明明是整目录拷贝,怎么可能创建不了目录。于是打开资源管理器去确认,发现project_copy.runs这个文件夹确实存在,但里面只有一个空的synth_1子目录,而原工程里的synth_1下本来应该有一堆runme.log、.Xil、缓存文件。最诡异的是,我再仔细看,连synth_1这个文件夹都只有一层壳,里面什么都没有。

这就是典型的“工程复制后目录状态与工程配置不一致”引发的连锁反应。Xilinx 在报这个Common 17-1294错误时,通常不会只报一次,它会先报创建目录失败,紧接着往往还会跟一串类似ERROR: [Common 17-170]的路径解析失败,或者干脆直接中断综合流程。要理解为什么复制个工程都能整出这么多事,得先搞清楚 Vivado 在启动综合时对目录做了什么。

1.1 报错文本拆开看

[Common 17-1294]这条错误本身的意思非常直白:Vivado 尝试在指定路径创建目录,但失败了。失败原因通常有三类:

  • 路径对应的父目录不存在,而且 Vivado 没有自动创建父目录的权限。
  • 路径指向的位置是一个已存在的文件,而不是目录,导致同名冲突。
  • Vivado 进程对目标磁盘分区没有写入权限。

但放到“工程复制”这个具体场景里,情况更复杂。因为当你用操作系统自带的复制粘贴功能拷贝整个 Vivado 工程目录时,Windows 不会百分百保证每个隐藏文件、每个目录属性、每一条路径关联都原样搬过去。尤其当原工程的runs目录下已经有上一次综合生成的中间文件时,复制出来的副本很容易出现“目录层级稀疏”的情况——表面上文件夹都在,但内部结构被截断了。Vivado 一运行synth_1子流程,发现需要的目录层级不完整,就会尝试自行创建,结果因为种种原因创建失败,于是报出Unable to create directory。

1.2 这个错误的“高发人群”

我后来在几个 FPGA 技术交流群里问了问,发现踩到同一个坑的人还挺多,基本集中在几个场景:

  • 拿别人的工程直接用,压缩包解压后路径变了。
  • 自己用“复制粘贴”大法复制整个工程,像Copy一个 Word 文档那样随意。
  • 把工程放在网盘同步目录、U盘、移动硬盘上,复制过程中文件状态不稳定。
  • 工程路径里带了中文、空格、括号等特殊字符,复制后路径解析出现偏差。

如果你是这几类用户,那这篇内容值得看完,后面的排查步骤都是我实打实验证过的。

2. 排查思路:不要上来就重装软件

很多朋友一看到 Vivado 报错,第一反应是“坏了,软件不行了”,然后开始重装、换版本、装驱动,折腾一整天。我踩过这种坑,负责任地告诉各位:Common 17-1294这类错误极少是软件安装本身的问题,绝大多数是工程文件状态和路径环境的问题。重装Vivado不仅浪费时间,而且大概率解决不了。

正确的排查顺序应该是:

  1. 检查工程路径本身是否合法。
  2. 检查目标目录的实际状态。
  3. 检查 Vivado 进程对目录的权限。
  4. 检查复制过程中是否丢失或损坏了工程元数据。
  5. 如果以上都没问题,再考虑用 Vivado 自带的归档/导出功能重新生成工程。

下面我按照这个顺序,把每一步的具体操作和判断标准讲清楚。

2.1 第一步:先确认路径符不符合 Vivado 的“脾气”

Vivado 对工程路径相当挑剔。根据 Xilinx UG892 的说明,工程路径中不能包含中文字符、不能有空格、不能以数字开头(在某些版本中),路径总长度也有隐性限制。很多人复制工程时图省事,直接把文件夹命名为工程副本_final_v2或者my project copy,这种路径在 Windows 资源管理器里看着没问题,但 Vivado 内部用的是 Tcl 脚本解析路径,空格和中文很容易在拼接命令时炸掉。

我之前遇到过一个案例,朋友把一个工程放在D:\My Projects\uart demo\目录下,复制后工程一综合就报Common 17-1294。我把路径里的空格去掉,改成D:\Projects\uart_demo\再重新打开,问题直接消失。所以遇到这个报错,先别急着改工程内容,第一件事是把工程放到一个纯英文、无空格的短路径下试试。

打个比方:Vivado 的路径解析就像一个只认标准普通话的语音助手,你用方言跟它说话,它听不太懂但也不会明说,最后就憋出一个莫名其妙的错误。路径里有空格和中文,就是这个“方言”的典型代表。

2.2 第二步:检查复制的工程目录里有没有“半截货”

我在文章开头说的那个情况——synth_1文件夹只有一层空壳——其实非常有代表性。用 Windows 的资源管理器复制粘贴大目录时,如果目录层级很深、文件很多,偶尔就会出现“复制”操作提前结束但系统没有报错的情况。尤其是当源目录里正有别的程序在写文件,或者杀毒软件正在扫描时,复制出来的副本很可能缺文件。

判断方法很简单:对比原工程和复制工程的runs目录、.srcs目录的大小和文件数量。在 Windows 下可以右键属性看“大小”和“包含文件数”。如果复制出来的目录文件数明显少于源目录,那这个复制就是不可靠的,别再在这个副本上浪费时间排查了,重新复制一遍,或者干脆走 Vivado 官方的导出流程。

2.3 第三步:看报错目录是否真实存在

如果你已经确定路径是干净的了,那就要去文件系统里实地检查。在 Vivado 报错提示的那个路径上,打开资源管理器,一层层点进去看,注意两件事:

  • 路径上的每一级目录是否存在。
  • 目标目录是不是被一个同名文件占用了。

第二点很容易被忽略。我见过有人工程目录下有一个文件叫synth_1(没有扩展名),同时还需要创建一个同名目录,Windows 不允许文件和目录同名,Vivado 也就跟着报Unable to create directory。这种文件通常是不小心的历史遗留,删掉就行。

还有一个冷门情况:目标路径的某级父目录其实是个“快捷方式”或者“软链接”(Symlink)。Vivado 在某些版本中对软链接处理得不好,可能在解析真实路径时失败。如果检查发现目录实际是快捷方式,建议把真实目录直接搬过来。

2.4 第四步:考虑读写权限问题

这一步在 Linux 环境下尤其重要,Windows 下相对少一些,但也不是没有。Vivado 运行综合和实现时,会在工程目录下创建.runs、.cache、.hw等文件夹,同时往里面写入日志、检查点、网表等大量中间文件。如果工程所在目录被设置为只读,或者当前用户对该目录没有“完全控制”权限,Vivado 就会在创建目录或写入文件时失败。

在 Windows 上检查权限:

  • 右键工程根目录,选“属性”。
  • 切到“安全”页签,看当前用户是否有“修改”和“写入”权限。
  • 如果没有,点“编辑”添加权限。如果怕麻烦,可以直接把整个工程目录的只读属性去掉。

在 Linux 上就简单了:

chmod -R u+rwx /path/to/project

做了这个操作之后,再重新打开工程跑综合,大概率能过。

3. 解决过程的完整实录

理论讲了一堆,我把我那个工程从报错到恢复的全过程按时间线写出来,你可以对照着抄作业。

3.1 第一次尝试:新建同名目录手动“补位”

最开始我看到Unable to create directory ... synth_1,想走捷径:你 Vivado 不是创建不了目录吗?那我手动给你建好不就完了。于是我在资源管理器里进了project_copy.runs,右键新建文件夹,起名synth_1,然后满怀期待地再次点击 Run Synthesis。

结果呢?报错变了,从Common 17-1294变成了:

ERROR: [Common 17-170] Unable to open file 'C:/.../project_copy.runs/synth_1/.Xil/Vivado-xxxxx/_xocc_compile_...'

也就是说,目录虽然是有了,但 Vivado 在综合过程中还需要往里面写更多的临时子目录和小文件,比如.Xil缓存目录、runme.sh脚本等,仅仅建一个空壳目录根本不够。Vivado 是按一套固定流程去生成整个目录树的,少了任何一层它都会继续尝试创建,而创建失败的根因并没有被“手动补位”解决。

这次尝试让我明白了一件事:症状在“创建目录”,但病因是“复制过程产生的目录树损坏”,手动补一个文件夹是在治标,不是治本。

3.2 第二次尝试:重置工程运行状态

抱着“可能只是中间状态乱了”的想法,我用之前做过的一个操作——在 Vivado 的 Tcl Console 里执行:

reset_run synth_1

这个命令会把指定的综合运行配置重置,删除.runs/synth_1下的生成文件,把运行状态恢复为“未运行”。理论上,如果只是运行状态记录和实际目录不一致,重置后问题应该消失。

但结果依然不行。Console 里先打印了一行WARNING: [Vivado 12-507] No runs in the project之类的话,然后我再启动综合时,老错误原封不动地回来了。这说明工程元数据里记录的运行信息本身可能就有问题,不是单纯的重置能解决的。

到这里我开始意识到:这个复制工程除了目录树有问题,可能连.xpr工程文件内部记录的路径、运行配置都已经和外部文件系统对不上了。继续在原副本上修补,成本会越来越高。

3.3 关键转折:用 Vivado 的 Tcl 命令干净地重建工程

后来我想通了,与其在坏副本上修修补补,不如回到“源工程”这个一切正常的基准点,用 Vivado 自己的导出/导入机制来生成一份干净副本。这才是治本的做法。

具体命令如下。在源工程已打开的前提下,在 Tcl Console 里执行:

# 关闭当前工程 close_project # 以只写模式打开目标工程(路径自定义,但要保证无中文无空格) open_project C:/Work/template_uart/template_uart.xpr # 将当前工程归档到一个压缩包 archive_project -include_runs -include_generated_files C:/Work/template_uart_archive.zip

执行完archive_project后,Vivado 会把你当前工程的所有源文件、约束文件、IP配置、运行配置,连同必要的中间生成文件,全部打包进一个 zip。这个压缩包是自包含的、干净的、路径无关的。

然后我在资源管理器里新建一个目录,比如C:/Work/new_project/,把刚才的 zip 解压进去,打开解压后的.xpr,再跑一遍综合。这次问题彻底消失了。

这里想补充一下archive_project的几个参数含义:

  • -include_runs:把已有的综合/实现运行配置一起打包,方便新工程直接接着跑。
  • -include_generated_files:把 IP 生成的文件也打进去,避免在新机器上重新生成 IP 时出现兼容性或者网络下载问题。
  • 如果不加参数,默认只归档源文件,IP 和运行配置会在新工程中重新生成。

3.4 为什么“归档+解压”能根治问题

因为archive_project是 Vivado 自己生成的压缩包,里面的路径引用是经过内部归一化处理的,不会像操作系统的复制粘贴那样把一个深层目录结构搬得七零八落。更关键的是,归档包重新解压后,工程文件和文件系统之间的对应关系是由 Vivado 自己生成的,runs目录、sources目录的层级关系完全符合 Vivado 内部的预期。

这就像是你请搬家公司和自己在凌晨搬家的区别。自己搬,家具可能少几件、装错了箱子;搬家公司按清单打包,到了新家按清单归位,虽然贵一点但心里有底。

3.5 如果源工程也打不开怎么办

如果手头连一个状态完好的源工程都没有,或者源工程本身就是从别人那里复制来的,那也别慌。还有一种更基础的修复路径:

  1. 用记事本打开.xpr文件,检查里面的Project标签下的Version、Part等信息是否完整。
  2. 如果.xpr文件本身损坏严重,可以新建一个空工程,选同一块 FPGA 型号,然后通过Add Sources手动把.v、.vhd、.xdc文件加进去。
  3. 对于 IP,建议直接用 IP Catalog 重新生成,虽然费点时间,但比抱着一个可能损坏的 IP 副本硬啃要好得多。

这个方法其实就是“放弃治疗,重新接骨”。对于代码源文件完好、但工程元数据损坏的情况,往往是最快的出路。

4. 复制工程前应该做什么:一套靠谱的规范化流程

踩过这个坑之后,我现在复制任何 Vivado 工程,都不再直接去文件管理器里 Ctrl+C、Ctrl+V 了。步骤如下,照着做基本不会再碰到Common 17-1294:

4.1 先清掉工程里的“运行垃圾”

复制工程前,先打开 Vivado,打开要拷贝的工程,然后在 Tcl Console 里执行:

# 删除综合运行的生成文件 reset_run synth_1 # 删除实现运行的生成文件 reset_run impl_1

如果工程时间比较久了,里面可能残留很多.cache、.runs下的硬编译产物,这些文件不仅体积巨大而且容易在复制时引发权限和目录问题。你也可以手动在资源管理器里,把工程目录下的:

  • .runs目录
  • .cache目录
  • .hw目录
  • .gen目录
  • .Xil目录(这是隐藏目录,Windows 下要开“显示隐藏项目”才看得到)

整个删掉,然后关闭工程。这样剩下的就是一份纯源代码、约束、IP定义和工程配置,体积小、结构简单,复制时几乎不会出问题。

我用一个表格总结一下哪些文件建议保留、哪些建议删除:

项目建议原因
.srcs目录保留源代码、约束都在这里,核心资产
.xpr文件保留工程入口
.runs目录删除综合/实现的中间产物,占用空间大
.cache目录删除缓存文件,可重新生成
.hw目录删除硬件相关临时文件
.gen目录删除IP 生成缓存
.Xil目录(隐藏)删除调试缓存

经过这一轮“瘦身”后,工程目录会清爽很多,复制速度和成功率都会大幅提高。

4.2 复制后立即执行的“三查”

复制完成并打开新工程后,不要急着点 Run Synthesis,先按下面三个步骤快速体检:

  1. 查看Sources窗口里的文件图标,看是否有文件前出现黄色的感叹号。出现感叹号说明文件路径缺失,需要右键Refresh或者重新添加。
  2. 打开Project Settings -> Synthesis,确认 Top Module 名字没有变红、没有变成 Unknown。
  3. 在 Tcl Console 里执行:
get_property DIRECTORY [get_projects]

检查返回的路径是不是新工程的实际路径,而不是老的源工程路径。如果路径还是老的,需要在Project Settings -> General里手动改一下工程目录。

这个“三查”流程能帮你把大部分复制后遗症提前暴露出来,避免在综合时报错后才手忙脚乱。

4.3 直接用 Vivado 的“Project Manager”归档功能

如果你实在记不住 Tcl 命令,没关系,GUI 路径也可以:

  1. 打开工程,点击菜单栏File -> Project -> Archive。
  2. 在弹出的对话框中勾选Include runs和Include generated files(如果新工程里不想保留中间结果,也可以不勾)。
  3. 设置归档 zip 的保存路径,点确定。

归档完成后,把 zip 发到任何一台机器上解压打开就行,这套流程和 Tcl 命令效果完全一样,只是多了个图形界面。

5. 常见问题与排查技巧实录

5.1 问题速查表

报错信息可能原因处理方式
Common 17-1294 Unable to create directory复制导致目录树损坏/权限不足/路径非法优先检查路径和权限,必要时使用archive_project重新导出
Common 17-170 Unable to open file目录存在但文件缺失或占用删除对应运行目录,重新运行
黄色感叹号,文件丢失.srcs下源文件路径被改右键文件Refresh或重新 Add Sources
ERROR: [Project 1-481] No part selected工程元数据损坏打开工程设置重新选器件型号
综合能过,但实现报错routed property missing运行状态记录被破坏执行reset_run impl_1后重新跑

5.2 一个 Linux 下的特殊案例

我有一个做嵌入式方向的朋友,在 Ubuntu 下用 Vivado 2022.2,把工程复制到另一台机器后同样报了Common 17-1294。排查到最后,发现是复制时用了cp -r,但源工程里有个软链接目录指向了/home/user/old_project/runs,复制后那个软链接在新机器上指向了一个不存在的路径,Vivado 一尝试通过软链接创建子目录就直接失败。

解决方法是:复制前先把软链接替换成实际目录的硬拷贝,或者在复制时使用cp -rL这个参数,让cp把链接目标的内容也复制过来,而不仅仅是复制一个指向旧路径的链接。

这个案例提醒我一点:Linux 下复制工程,cp参数的选择很关键。默认的cp -r复制软链接时只复制链接本身,不复制目标内容,这在普通文件场景下问题不大,但碰到 Vivado 这种高度依赖绝对路径解析的工具,就是实打实的坑。

5.3 如何从报错路径反推工程“秘密”

Vivado 报错信息里的路径其实很有信息量。当你在 Console 里看到:

[Common 17-1294] Unable to create directory 'C:/Users/xxx/Desktop/project_copy/project_copy.runs/synth_1'

注意看project_copy/project_copy.runs这段。正常工程里,runs目录应该是工程目录的子目录,格式通常是<工程名>.runs。如果你的工程目录叫project_copy,那运行目录就是project_copy.runs。但当路径里出现project_copy/project_copy.runs,说明复制后的目录嵌套结构发生了变化,很可能你复制的时候,把整个项目文件夹放入了另一个同名文件夹里,比如原工程在A文件夹,你又把A整个拖进了B,导致工程实际路径比.xpr文件里记录的路径多了一层。

这种情况下,最简单的修复方法不是改.xpr,而是把工程的物理路径调整成和.xpr内部记录的一致。说白了就是:要么移动文件夹,要么用archive_project重新生成一份对齐的工程文件。

5.4 关于杀毒软件和网盘的全员警告

我后来复盘自己第一次踩坑的经过,怀疑还有一个潜在帮凶:杀毒软件实时防护。Windows Defender 扫描大目录时,会对每一个新建文件做一次实时的“行为检查”,在这个检查过程中,文件可能处于“半锁定”状态。如果此时 Vivado 尝试在同一个目录里创建子目录,系统可能返回一个“权限不足”的假信号,Vivado 就误报为Unable to create directory。

此外,如果你把工程放在 OneDrive、坚果云这类网盘同步目录下,网盘客户端的大文件同步也可能导致类似问题。复制出来的工程还没等本地完全落盘,就被网盘客户端“接管”上传了,导致 Vivado 读取时文件状态不稳定。

建议是:Vivado 工程这种大型、多文件、高频率读写的项目,老老实实放在本地磁盘的一个固定目录下,不要放到网盘同步目录或U盘上。这不是保守,是省时间。工程同步可以等关闭 Vivado 之后手动做。

6. 最后的几点心得

把Common 17-1294这个错误从头到尾解决完,我最大的感触是:很多 Vivado 工程迁移问题,根本不是工具链本身的问题,而是我们对“工程文件的结构”缺乏足够的敬畏。Vivado 的工程不像 Word 文档是一个单独文件,它是一个由几十个甚至上百个文件夹、配置文件、缓存目录组成的复合体。用复制普通文档的方式去复制它,出问题只是概率问题,不出问题才是运气好。

现在我自己处理工程复制的固定套路是:先在 Vivado 里reset_run清干净中间产物,然后用archive_project打包,再到新目录解压。整个过程多花不到三分钟,但能省下好几个小时排查错误的时间。如果你手头正好也被Common 17-1294卡住了,先冷静下来,按我上面说的顺序检查一遍:路径、权限、目录状态、归档导出。大概有九成以上的概率能直接解决。剩下那一成,多半是工程文件本身已经损坏到无法修复了,那就老老实实新建工程重新添加源文件吧。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询