1149_Makefile学习_Windows系统下Makefile gmake报process_begin: CreateProcess(NULL, ..., ...) failed.问题解决

本文讲述了作者在工作需求下重拾Makefile,经历从网络教程学习到Windows系统下编译失败的挑战,揭示了操作系统与make工具差异对Makefile的影响,以及后续的排查和解决方案。

    全部学习汇总: https://github.com/GreyZhang/g_makefile

    最近因为工作需求,得重新面对Makefile。我之前也通过各种脚本替代国Makefile的功能,比较傻瓜化但是其实对付一般的小工程还是可以的。那么为什么又回到了Makefile呢?因为我觉得或许这个也是一种方法论的体现,加上这也算是古老技术的传承,如果精通了处理问题或许会更加优雅。

    我有过几次直接读make手册最终失败告终的经历,这一次我放弃了啃读枯燥的手册,把方式转到了跟随网络教程上。每天花点时间了解一点点,也是想看到量变到质变的效果。前面几天其实还算是顺利,今天运行一个基本的历程的时候失败了。相应的makefile如下:

cc := gcc

objects = foo.o bar.o all.o

all: $(objects)

# These files compile via implicit rules

# Syntax - targets ...: target-pattern: prereq-patterns ...

# In the case of the first target, foo.o, the target-pattern matches foo.o and sets the "stem" to be "foo".

# It then replaces the '%' in prereq-patterns with that stem

$(objects): %.o: %.c

all.c:

    echo "int main() { return 0; }" > all.c

%.c:

    touch $@

clean:

    rm -f *.c *.o all

    最初的版本中gcc都没有赋值,我还是我修改过的。在windows系统下,使用gmake进行make的时候出现了一个错误。具体如下:

    尝试对比,没有跟例程代码发现任何差异。我好奇,去WSL下做了一下测试,没想到通过了。效果如下:

    那么,到底是为什么呢?难道是因为不同的操作系统之间会有差异?或者是make工具之间的差异?针对这方面,我做了一系列的尝试排查。

    首先,查看make工具的版本:

    这是WSL上的工具版本信息,接下来看Widnows下的gmake版本信息。

    巧合了!通过上面的信息查看,其实这两个就是一个工具的同一版本。那么,为什么会有差异呢?我试了我手头已经有的几个不同的make、gmake以及dmake,最终都没有成功。最后,还是回到了make的文档。首先搜索了windows关键词,没有看到什么特殊点。后来,逐个章节浏览,运气很好,一下子看到了一个可能的差异点。

    上面是文档的原文,从这里可以看得出来其实这个CC应该是大写的。但是我找到的例子里面是小写的,做一个简单的修改测试。

    Windows系统下顺利通过。make手册中的描述看信息应该是linux为主,不过以防万一一同测试了一下,功能依然是正常的。不过,两个环境下编译速度有着很大的差异,linux下的效率明显是要高一些的。

    或许,这算不上什么大的知识点,只是hack、学习过程中的小插曲。但是正是解决一个个类似小问题的过程,让我们的hack生活充满了快乐!

<think>我们正在解决一个在Windows环境下执行`mkdir -p obj`命令时出现的`CreateProcess`失败问题。根据引用[1]中的错误信息,我们看到类似的问题发生在执行`make clean`时,系统尝试执行`rm`命令但失败了,因为Windows命令提示符(cmd)默认不支持Unix风格的命令(如`rm`)。同样,`mkdir -p`也是Unix风格的命令,在Windows的cmd中不被识别。 解决方案: 1. 使用Windows等效命令:在Windows中,创建目录的命令是`mkdir`,但需要注意的是,Windows的`mkdir`默认不支持`-p`选项(即递归创建目录)。不过,在Windows中,`mkdir`命令在创建多级目录时不需要特别选项,它会自动创建路径中所有不存在的目录。因此,我们可以直接使用`mkdir obj`(如果obj是多级目录,比如`a/b/c`,也可以直接使用`mkdir a\b\c`)。 2. 如果是在Makefile中,我们可以使用条件判断来区分操作系统,以便在Windows和Unix-like系统上都能工作。例如,在Makefile中,我们可以这样写: ```makefile create_dir: if not exist obj mkdir obj ``` 或者,为了支持跨平台,我们可以使用: ```makefile ifeq ($(OS),Windows_NT) MKDIR_P = if not exist $(1) mkdir $(1) else MKDIR_P = mkdir -p $(1) endif obj: $(call MKDIR_P,obj) ``` 3. 使用Python的`os`模块:如果用户正在使用Python脚本,可以使用`os.makedirs`来创建目录,它会递归创建所需的目录,并且跨平台。例如: ```python import os os.makedirs('obj', exist_ok=True) # exist_ok=True 相当于 -p,如果目录已存在不会错 ``` 4. 使用`subprocess`模块:在Python中,我们可以使用`subprocess`模块来执行命令,并且可以避免直接使用操作系统的特定命令。引用[2]和[3]提供了关于`subprocess`和`os.popen`的信息。但注意,`os.popen`在失败时不会返回状态码,所以推荐使用`subprocess`。例如: ```python import subprocess import sys # 跨平台创建目录 if sys.platform == 'win32': subprocess.run(['mkdir', 'obj'], check=True) # 或者使用更安全的方式,因为Windows的mkdir可以创建多级目录 # 但注意:如果目录已经存在,mkdir会错,所以我们可以先检查 else: subprocess.run(['mkdir', '-p', 'obj'], check=True) ``` 不过,更推荐使用`os.makedirs`,因为它更简单。 5. 如果用户确实需要在Windows中使用类似Unix的命令,可以考虑安装Cygwin或MinGW,或者使用Windows Subsystem for Linux (WSL)。但这种方法需要额外的安装。 根据引用[1]的错误,用户可能是在Windows的cmd中直接运行了类似Unix的命令。因此,最简单的解决方案是使用Windows原生的命令替换。 针对用户的具体命令`mkdir -p obj`,在Windows cmd中可以直接替换为: ```cmd mkdir obj ``` 因为即使`obj`的父目录不存在,Windows的`mkdir`也会创建整个路径(与Unix的`mkdir -p`行为类似)。但是,请注意:在Windows中,如果目录已经存在,再次创建不会错(而Unix中如果没有`-p`则会错)。所以,在Windows中,`mkdir obj`可以安全地执行,如果目录已经存在,它会提示“子目录或文件 obj 已经存在”,但这不会导致进程失败(错误级别为0)。如果希望避免这样的提示,可以在Makefile中使用条件判断,或者使用上面提到的其他方法。 因此,我们建议用户将命令改为Windows支持的格式。如果是在Makefile中,请使用条件判断来适应不同的操作系统。 如果用户的问题是在某个脚本(如Makefile)中,那么修改该脚本以使用Windows命令即可。 注意:在Windows中,路径分隔符是反斜杠`\`,但在命令中也可以使用正斜杠`/`。因此,`mkdir a/b/c`在Windows中也是有效的,它会创建多级目录。 总结:在Windows中,请使用`mkdir obj`代替`mkdir -p obj`。 如果用户是在Python环境中,建议使用`os.makedirs`,这样更跨平台。 相关问题: 1. 为什么在Windows执行Unix命令会失败? 2. 如何在Makefile中编写跨平台的目录创建命令? 3. 如何使用Python跨平台地创建目录?</think>### 解决 CreateProcess 失败问题:`mkdir -p obj` 在 Windows 系统执行 `mkdir -p obj` 命令时出现 `CreateProcess` 失败错误,根本原因是 **Windows 命令提示符(CMD)不支持 Unix 风格的 `-p` 参数**。以下是详细解决方案: --- #### 方法 1:使用 Windows 原生命令 ```cmd :: 创建单级目录(obj 不存在时) mkdir obj :: 创建多级目录(自动创建父目录) mkdir subdir\obj ``` **说明**: Windows 的 `mkdir` 命令默认会递归创建路径中所有不存在的目录,无需 `-p` 参数。若目录已存在,系统会提示错误但不会中断进程[^1]。 --- #### 方法 2:通过 PowerShell 执行(推荐) ```powershell # -Force 参数等效于 Unix 的 -p New-Item -Path "obj" -ItemType Directory -Force ``` **优势**: - PowerShell 原生支持类 Unix 参数 - 兼容所有 Windows 系统(Win7+) --- #### 方法 3:在 Makefile 中跨平台兼容 ```makefile create_dir: ifeq ($(OS),Windows_NT) if not exist obj mkdir obj else mkdir -p obj endif ``` **原理**: - `$(OS)` 自动检测操作系统类型 - Windows 使用 `if not exist` 判断目录是否存在[^1] --- #### 方法 4:使用 Python 跨平台脚本 ```python import os import sys path = "obj" try: os.makedirs(path, exist_ok=True) # exist_ok=True 等效于 -p print(f"目录创建成功: {path}") except OSError as e: sys.exit(f"错误: {e.strerror}") ``` **执行方式**: ```cmd python create_dir.py ``` --- ### 关键问题分析 | 问题原因 | 解决方案 | |------------------------|----------------------------| | CMD 不支持 `-p` 参数 | 改用 `mkdir` 无参数形式 | | 路径含特殊字符 | 用双引号包裹路径 `mkdir "my dir"` | | 权限不足 | 以管理员身份运行 CMD | | 防病毒软件拦截 | 临时禁用安全软件 | > **注意**:Windows 路径分隔符使用反斜杠 `\`,但正斜杠 `/` 也可兼容,例如 `mkdir dir/subdir` 有效[^2]。 --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值