第一次在地铁上打开同事发来的工程压缩包,解压后在崭新路径下双击.xpr文件,Vivado 没进界面就直接弹了个ERROR: [Common 17-1294] Unable to create directory,我当时的反应和大多数人一样:这目录明明存在,怎么就不能创建了?后来反复折腾了大半天,才把这个报错的真正触发逻辑摸清楚。这不是一个随机故障,它基本就是“vivado工程复制”这个动作引起的病,而且只要理解了 Vivado 对工程目录的读写机制,这个错完全可以在三十秒内解决。
这篇文章就把我自己的排查过程和几种解决路径原原本本写出来,同时会把工程复制的正确姿势一并交代清楚。无论你是刚装好 Vivado 的学生,还是被这个错误卡住进度的工程师,这篇都值得看完。
1. 这个报错长什么样:先认清问题和它的出现场景
1.1 报错的字面信息与触发时机
[Common 17-1294] 这个错误号在 Vivado 里属于 “Common” 基础模块的报错,和具体的综合、布局布线流程无关,它主要发生在工具有写文件、建目录这种底层操作的时候。完整的报错长这样:
ERROR: [Common 17-1294] Unable to create directory 'E:/work/project_copy/project_1.runs/synth_1'字面意思很清楚:在指定路径下创建目录失败。但从我实际测试和线上搜索的情况看,这个报错出现的高频场景基本集中在下面这几类:
- 把整个 Vivado 工程文件夹从一台电脑复制到另一台电脑,然后在新机器上直接打开
.xpr文件。 - 把工程目录从网盘、U盘、压缩包中解压出来后打开。
- 从 Git 仓库 clone 整个工程下来后,在本地双击打开。
- 在同一个工程目录里,用
sync_project或者write_project_tcl等方式重建过工程,但没有清理干净旧缓存。
你会发现,这些场景有一个共同点——工程不是“从头新建”的,而是经历了文件系统的复制、移动、解压。Vivado 在打开工程时不仅读.xpr里的配置,还会同步检查一系列伴生目录是否可写,一旦它发现工程所在的路径结构有问题,就直接在打开阶段抛出 Common 17-1294。
1.2 为什么“工程复制”场景最容易中招
这里有个关键点很多人没意识到:复制目录不等同于新建目录。Vivado 工程目录里包含的东西,比“源码 + .xpr”要多得多。你复制整个工程文件夹的时候,带过去的不仅是原理图、约束、IP 配置,还包括.Xil缓存、*.runs下的综合和实现结果、*.cache下的流程缓存、*.hw下的硬件服务器状态,以及两个很有迷惑性的文件vivado.jou和vivado.log。
这些文件在对的机器上是“工程记忆”,但复制到新环境后,它们反而成了“障碍”。比如.Xil是 Vivado 运行时创建的临时目录,里面保存了 GUI 布局、日志、甚至一些进程相关的锁文件。你在旧机器上关 Vivado 时的状态、文件句柄、绝对路径引用都会被写进这些缓存里。复制过来后,如果文件被标记成只读,或者路径和缓存中记录的旧路径不一致,Vivado 试图在新的工作区目录下重建这些目录时就会失败。
另外还有一个 Windows 平台的经典陷阱:资源管理器右键复制文件夹时,如果目标位置原本的父目录有特殊权限,或者复制的源是从“压缩文件夹”里直接解出来的,整个目录树的文件会被标记上只读属性。Vivado 在创建.runs/synth_1这种子目录时启动一个递归检查,发现父目录只读,就会返回Unable to create directory。
1.3 存在误导性的“只读”陷阱
这个报错的迷惑性在于:你打开文件管理器,肉眼看到目录明明存在,右键属性里也只觉得“好像没有限制”。但 Vivado 判断可写性时用的是底层系统调用,它不会去检查资源管理器属性的那个勾选状态。在 Windows 上,attrib显示为R(只读)的文件,看起来是正常的,甚至你可以正常打开它;但当你用程序去创建一个新的子目录时,系统会因为上级目录的 ACL 权限或 ReadOnly 标志返回“拒绝访问”,Vivado 就把它包装成了“Unable to create directory”。
换句话说,这个错误的根因很多时候不是路径本身有毛病,而是当前用户对这个路径下的写入权限不完整。排查的时候不要光盯着报错路径本身,还要看它上一级、上上级目录的权限状态。
2. 排查链路:从周边日志到文件系统逐层定位
我的习惯是,遇到 Vivado 报错不要急着删缓存、重建工程,先花十分钟把这个错误的触发链路完整还原一遍。之后你能省下更多时间。
2.1 先复现一次:记下完整报错路径
把 Vivado 弹出来的报错完整复制出来,不要只盯着错误码。重点看:Unable to create directory后面跟着的具体路径是哪个,是.runs还是.cache,还是.Xil。
举个例子:
ERROR: [Common 17-1294] Unable to create directory 'C:/Users/Administrator/AppData/Roaming/Xilinx/Vivado/2023.2/.Xil'这个路径已经不是工程目录本身了,而是 Vivado 在用户数据目录下的全局缓存。如果你看到的是这类路径,就说明问题直接出在系统用户目录的写入权限上,和你的工程文件一点关系都没有。这种情况往往是你用了精简版系统、用户目录被迁移过、或者杀毒软件拦截了对 AppData 的写入。
2.2 检查工程目录的只读属性与 ACL
进入报错路径所在的根目录,我建议用命令行而不是资源管理器来检查状态。打开 CMD,进到工程的上层目录,比如工程在E:\work\project_copy,就执行:
attrib "E:\work\project_copy" /s /d这条命令会把整个目录树下所有文件、子目录的属性全列出来。你要留意输出结果里每个路径前面有没有R标志。如果一批文件都是R,那你遇到的就是典型的复制引发的只读问题。
注意,attrib /s /d的输出可能很长,不要嫌麻烦。直接把它输出到一个文本文件里再搜:
attrib "E:\work\project_copy" /s /d > attr_result.txt然后用文本编辑器搜索R,看看带R标记的是不是大量集中在.Xil、.runs、.cache这类目录下。如果是,那就验证了第一个判断。
2.3 顺着 vivado.log 找线索
如果错误发生在打开工程的过程中,Vivado 其实已经往工程目录写了一个vivado.log。这个文件是文本格式,直接打开,搜索ERROR或者CRITICAL WARNING。但更有用的反而是报错出现之前的几条 INFO 记录。
比如我遇到过一种情况:vivado.log里在报错前出现了这样的记录:
INFO: [Common 17-206] Removing stale directory 'E:/work/project_copy/project_1.runs/synth_1'注意这个Removing stale directory,它说明 Vivado 认为这个目录是“过期的”,要删掉重建。如果这个目录被某个还活着的进程占用(比如你之前的 Vivado 没关干净、或者杀毒软件正在扫描),删除动作就会失败,随后立刻触发 17-1294。
所以看到vivado.log里的上下文很关键。它可以帮助你确定是“创建新目录”失败,还是“清理旧目录”失败。
2.4 确认是不是环境变量和系统临时目录的问题
还有一种隐蔽情况:报错路径出现在%TEMP%目录下面。Vivado 生成比特流、启动仿真的过程中,会在系统临时目录里创建一些中间文件。如果你用了一些系统优化工具把TEMP路径改到了非标准位置,或者那个路径有权限限制,就会导致 Vivado 的临时目录创建失败,报出 17-1294。
排查方法是:
echo %TEMP% echo %TMP%确认这两个路径指向的位置存在且可写。自己手动在这个路径下创建一个文件夹再删除,能成功就说明系统临时目录没有大问题。
3. 可落地的解决步骤:按风险从低到高排列
下面这些方案是从风险最低、操作最轻的方式开始排的。建议顺序执行,不要一上来就删整个工程。
3.1 方案A:删除 .Xil、vivado.jou、vivado.log 后重开
这是我在大多数情况下第一个尝试的方案,也是成功率最高的一个。
具体操作:
- 完全关闭 Vivado。
- 在工程目录中找到
.Xil文件夹,整个删除。 - 同时删除
vivado.jou和vivado.log这两个文件。 - 重新双击
.xpr打开工程。
为什么这样有效?.Xil是 Vivado 打开工程时创建的运行时缓存,里面包含了很多和旧路径绑定的临时状态。工程被复制之后,.Xil里的信息已经和当前路径完全对不上,Vivado 思考要不要更新它、重建它,如果发现它只读或者被占用,就会卡住报错。删掉之后,Vivado 会认为这是第一次打开这个工程,干净利落地重建缓存。
vivado.jou是命令记录文件,vivado.log是日志文件。它们复制过来时可能是只读的,也可能是零字节的。删掉它们不会影响工程本身,Vivado 每次启动都会重新生成。
3.2 方案B:用 attrib/icacls 解除只读
如果方案A执行完依然报错,那基本可以确定是文件属性或 ACL 权限的问题了。
在工程上层目录执行:
attrib -r -s -h /s /d "E:\work\project_copy"这个命令会递归地移除project_copy目录下所有文件和目录的只读、系统、隐藏属性。它解决的是资源管理器复制时带来的属性继承问题。
但attrib有个局限,它处理不了 Windows 的 ACL 权限表项。如果某些文件或者文件夹的 ACL 里明确禁止当前用户写入,光去掉只读属性没用。这种情况要用icacls重置权限:
icacls "E:\work\project_copy" /reset /T /C/T表示应用到所有子目录和文件,/C表示遇到错误继续执行不要中断。/reset会把 ACL 重置为继承的默认权限。如果你的工程放在 NTFS 分区下,加上这一条基本能解决 90% 的权限类问题。
注意:图形界面右键改只读属性不是不能用,但有的时候它只能改第一层目录,不会递归到子文件夹。所以我强烈建议用命令行。
3.3 方案C:用 write_project_tcl 导出脚本重建
如果你已经能在只读状态下打开工程(或者在报错之前能用 TCL 命令访问工程),另一个比较安全的方案是让 Vivado 把整个工程以 TCL 命令的形式导出来,换一个路径重新生成。
在 Vivado TCL Console 里执行:
open_project E:/work/project_copy/project_1.xpr write_project_tcl -force E:/work/project_rebuild.tcl close_project然后关闭 Vivado,新建一个目录,比如E:/work/project_new,打开 Vivado,在 TCL Console 里执行:
cd E:/work/project_new source E:/work/project_rebuild.tclwrite_project_tcl会把工程的源文件、约束、IP、器件型号、编译选项全部以 TCL 命令的方式记录下来。源文件如果在原工程目录里,脚本会以相对路径引用,所以你需要把原工程目录里的源码目录也一并保留好。这种方式相当于让 Vivado 在全新路径下重新组装工程,所有缓存、临时目录、日志都是新生成的,从根上规避了复制带来的脏状态。
3.4 方案D:删除运行产物目录后重新打开
如果.xpr能打开,但是综合或者生成比特流时报 17-1294,那问题更多出在旧的运行产物上。
这时可以手动删除这些目录:
project_1.runs:综合、实现、比特流生成的全部运行结果。project_1.cache:流程缓存。project_1.hw:硬件服务器相关文件。project_1.sim:仿真运行目录。
这些目录都是生成物,删掉之后 Vivado 会在下次运行时重新创建。真正需要保留的是project_1.srcs目录——那是你的源代码、约束和 IP 定义所在。
删完之后重新打开工程,Vivado 会提示你工程不完整之类的话,不用慌,让它重新运行一个综合或者直接打开,它会发现没有旧的.runs结果,于是重新创建目录和检查点。
3.5 方案E:搬迁到短路径、纯英文目录
这是解决很多莫名其妙问题的“兜底操作”。Windows 下路径长度超过 260 字符会导致CreateDirectory失败,这是文件系统层面的硬限制。Vivado 工程目录层级本来就深,比如:
E:/work/project_copy/project_1.runs/synth_1/.Xil/Vivado-2023.2如果工程所在的父目录还带中文、空格、特殊符号,就更容易触发底层 API 失败。Vivado 的报错文案是“Unable to create directory”,但真实原因其实是“路径太长”或“路径含有非法字符”。
我的建议很简单:把工程放到一个干净的短路径下,比如D:\fpga\prj,并且确保整个路径中只有英文字母、数字、下划线和斜杠。这一步虽然看起来低级,但确实能救回一部分死活解不了的 17-1294。
哪些目录可能导致路径过长:
| 工程目录占用因素 | 示例 | 影响程度 |
|---|---|---|
| 父目录层级过深 | C:\Users\张三\Desktop\工作\2023\FPGA项目A-最终版\克隆工程 | 高 |
| 工程名过长 | pll_test_system_ultrasonic_fft_analysis_prj | 中 |
| 用户名含中文 | C:\Users\李四\ | 高 |
| 目录含空格 | C:\my works\fpga project | 中 |
4. 根治思路:如何正确复制和搬迁Vivado工程
4.1 复制前先做的事:正常关闭和归档
很多人复制工程的时候,Vivado 还开着,直接拿资源管理器把文件夹 Ctrl+C、Ctrl+V。这是最糟糕的做法,因为当时的打开状态会把文件句柄锁定、把运行中的进程临时文件写进目录。复制出来的工程处于“半关闭”状态,拿到新机器上自然容易触发各种奇怪问题。
正确做法是:在旧机器上把 Vivado 完全退出,确认没有xvlog、xvsim、vivado进程在后台跑。然后工程目录里的vivado.jou和vivado.log是关闭时的最终状态,这些没问题,但.Xil最好直接清理掉再压缩打包。
4.2 三种可用的工程迁移方式对比
我实际用过三种迁移方式,下面把它们列成表格,覆盖各自的适用场景和使用注意点。
| 迁移方式 | 操作步骤 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 全目录直接复制 | 复制整个工程文件夹 | 简单粗暴 | 极易带过去脏缓存和权限问题 | 同机、同用户、路径完全不变的备份 |
| 只复制 .xpr + srcs | 只保留工程文件和源码目录,删掉 .runs/.cache/.Xil 后再复制 | 干净,体积小 | 重新打开后需要重新跑综合 | 跨电脑复制,预算内推荐 |
| write_project_tcl 导出重建 | TCL 导出整个工程的创建脚本,在新机器 source | 工程完全是新生成的,无状态残留 | 需要确认源码路径引用正确 | 路径变化较大、需要长期维护的工程 |
第二种方式其实是个很好的折中:工程文件.xpr和srcs目录是核心,其他全部可以不要。把这两个东西压缩打包,到新机器上解压后,双击.xpr,Vivado 会发现.runs不存在,然后自动把所有运行目录重建出来。实测下来,这种方式很少出现 Common 17-1294。
4.3 复制后的校验清单
无论是用哪种方式复制,在打开工程前都建议按下面这个清单过一遍:
- 确认当前 Windows 用户对工程目录有完全控制权,右键属性 → 安全 → 用户 → 完全控制是勾选状态。
- 检查路径里没有中文和空格,工程目录层级不超过 3 层。
- 确认工程名本身不是
temp、test这类敏感词,避免个别工具链对特殊名称处理不一致。 - 打开工程前先删除
.Xil目录。 - 确认新机器上 Vivado 版本和旧机器一致,或者至少是更高版本。低版本打开高版本工程,本身就会报一堆兼容错。
5. 从报错日志逆向排查同类工具问题的通用思路
5.1 Vivado日志体系:去哪找、看什么
Vivado 的日志其实是分层的,我习惯把下面这几个文件按顺序看:
vivado.log:当前工程目录下的运行日志,覆盖最近一次 GUI 操作。vivado.jou:命令历史记录,每一条 TCL 命令都会被记录下来。.Xil下的日志:通常名字类似Vivado-2023.2-pid1234,包含启动时的早期信息。
遇到 17-1294,优先看vivado.log,搜ERROR关键字。但要注意,vivado.log里报错的上一行往往藏着真正的线索,比如“Attempting to create directory ... from path ...”之类的信息。如果只是孤立的一个错误,没有上下文,那大概率是权限问题,而不是路径本身的问题。
5.2 “无法创建目录/文件”错误的家族现象
Common 17-1294 不是一个人在战斗,Vivado 里还有一批类似的“文件系统操作失败”类报错,它们的根因往往是同一个:
| 错误码 | 报错内容 | 常见根因 |
|---|---|---|
| Common 17-1294 | Unable to create directory | 权限、只读属性、路径过长 |
| Common 17-1300 | Failed to create file | 文件被占用、磁盘空间不足 |
| Common 17-1293 | Unable to open file | 文件不存在、路径含中文 |
| Common 17-155 | Cannot modify the read-only file | 工程被标记为只读 |
| Common 17-56 | No such file or directory | 路径引用失效 |
如果你复制工程后遇到的是上面表格里其他报错,排查思路也是一样的:先确认权限属性,再确认路径有效性,最后再考虑重导工程。
5.3 几个容易误判的“假目录”问题
最后补充几个我亲手踩过的坑,它们表面上都是 17-1294,但实际上和目录创建没有直接关系。
一个是工程路径里带上了网盘同步目录。比如C:\Users\admin\OneDrive\FPGA_Project,OneDrive 会把整个目录同步到云端,复制时会把一些文件标记为“在线文件”,实际数据还没有下载到本地。Vivado 一看目录在,但读取时发现内容缺失,尝试创建目录又因为 OneDrive 的文件占位符问题失败。这种场景下,把工程移出网盘同步目录再打开,问题立刻消失。
另一个是杀毒软件实时防护在复制时把.Xil、*.runs下的可执行文件拦截,导致 Vivado 去释放内部校验文件时创建不了目录。这种情况一般会在报错日志里看到类似“Access is denied”的信息,临时关闭实时防护再验证一次就能判断出来。
最后一个是在 Linux 环境下用scp或者rsync复制工程后,文件属主变成了别的用户,Vivado 运行用户对目录没有写权限。这种场景下chmod -R u+w project_dir就能解决问题。注意这个场景在 Windows 上对应的是“以管理员身份运行”,但实际我遇到的情况是除了管理员,普通用户就没法打开工程,必须整体给当前用户授权。
我个人在实际操作中的体会是,遇到这种“看起来没有道理”的文件系统报错,最忌讳着急删掉整个工程重新建。Vivado 的工程文件结构虽然复杂,但它的报错逻辑其实是诚实的——它说创建不了目录,那系统层面一定有某个东西阻止了这次创建。把这个阻碍找到,比重新搭一次工程要省力得多。如果你现在已经遇到了 17-1294,按上面方案A到方案E逐个试一遍,大概率在第三步之前就解决了。