第一次在地铁上打开同事发来的工程压缩包解压后在崭新路径下双击.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 还开着直接拿资源管理器把文件夹 CtrlC、CtrlV。这是最糟糕的做法因为当时的打开状态会把文件句柄锁定、把运行中的进程临时文件写进目录。复制出来的工程处于“半关闭”状态拿到新机器上自然容易触发各种奇怪问题。正确做法是在旧机器上把 Vivado 完全退出确认没有xvlog、xvsim、vivado进程在后台跑。然后工程目录里的vivado.jou和vivado.log是关闭时的最终状态这些没问题但.Xil最好直接清理掉再压缩打包。4.2 三种可用的工程迁移方式对比我实际用过三种迁移方式下面把它们列成表格覆盖各自的适用场景和使用注意点。迁移方式操作步骤优点缺点适用场景全目录直接复制复制整个工程文件夹简单粗暴极易带过去脏缓存和权限问题同机、同用户、路径完全不变的备份只复制 .xpr srcs只保留工程文件和源码目录删掉 .runs/.cache/.Xil 后再复制干净体积小重新打开后需要重新跑综合跨电脑复制预算内推荐write_project_tcl 导出重建TCL 导出整个工程的创建脚本在新机器 source工程完全是新生成的无状态残留需要确认源码路径引用正确路径变化较大、需要长期维护的工程第二种方式其实是个很好的折中工程文件.xpr和srcs目录是核心其他全部可以不要。把这两个东西压缩打包到新机器上解压后双击.xprVivado 会发现.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-1294Unable to create directory权限、只读属性、路径过长Common 17-1300Failed to create file文件被占用、磁盘空间不足Common 17-1293Unable to open file文件不存在、路径含中文Common 17-155Cannot modify the read-only file工程被标记为只读Common 17-56No such file or directory路径引用失效如果你复制工程后遇到的是上面表格里其他报错排查思路也是一样的先确认权限属性再确认路径有效性最后再考虑重导工程。5.3 几个容易误判的“假目录”问题最后补充几个我亲手踩过的坑它们表面上都是 17-1294但实际上和目录创建没有直接关系。一个是工程路径里带上了网盘同步目录。比如C:\Users\admin\OneDrive\FPGA_ProjectOneDrive 会把整个目录同步到云端复制时会把一些文件标记为“在线文件”实际数据还没有下载到本地。Vivado 一看目录在但读取时发现内容缺失尝试创建目录又因为 OneDrive 的文件占位符问题失败。这种场景下把工程移出网盘同步目录再打开问题立刻消失。另一个是杀毒软件实时防护在复制时把.Xil、*.runs下的可执行文件拦截导致 Vivado 去释放内部校验文件时创建不了目录。这种情况一般会在报错日志里看到类似“Access is denied”的信息临时关闭实时防护再验证一次就能判断出来。最后一个是在 Linux 环境下用scp或者rsync复制工程后文件属主变成了别的用户Vivado 运行用户对目录没有写权限。这种场景下chmod -R uw project_dir就能解决问题。注意这个场景在 Windows 上对应的是“以管理员身份运行”但实际我遇到的情况是除了管理员普通用户就没法打开工程必须整体给当前用户授权。我个人在实际操作中的体会是遇到这种“看起来没有道理”的文件系统报错最忌讳着急删掉整个工程重新建。Vivado 的工程文件结构虽然复杂但它的报错逻辑其实是诚实的——它说创建不了目录那系统层面一定有某个东西阻止了这次创建。把这个阻碍找到比重新搭一次工程要省力得多。如果你现在已经遇到了 17-1294按上面方案A到方案E逐个试一遍大概率在第三步之前就解决了。