Skip to content

bobwenstudy/test_makefile_shell_env

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

使用Eclipse CDT build tools之后导致makefile环境错乱的问题

本人是windows开发环境,最近在搭建Eclipse CDT环境编译RiscV环境,然后使用了Eclipse的build tools环境,奇怪的是本地有很多makefile环境的c代码,会编译异常。

为了专门做了一些实验进行测试。

本例程所有相关代码在GitHub上,请自行下载。bobwenstudy/test_makefile_shell_env (github.com)

问题说明及验证

测试程序

为了说明发生什么,特意写了一个测试程序,以便对此问题进行分析。

main.c

#include <stdio.h>
int main()
{
    printf("hello, world\n");
    return 0;
}

Makefile,通过TEST_OS来区分不同测试环境,第8行打印当前的SHELLComSpec配置。

通过修改SHELL配置,即可调整当前的执行环境。

OUTPUT_DIR = output/obj
OBJECTS = $(OUTPUT_DIR)/main.o

MKD := mkdir
RM := del /q /s
FIXPATH = $(subst /,\,$1)

$(warning SHELL, $(SHELL), $(ComSpec))

ifeq ($(TEST_OS),1)
	MKD := mkdir -p
	RM := rm -rf
	FIXPATH = $1
endif

ifeq ($(TEST_OS),2)
	ifdef ComSpec
		WINCMD:=$(ComSpec)
	endif
	ifdef COMSPEC
		WINCMD:=$(COMSPEC)
	endif

	SHELL:=$(WINCMD)
	MKD := mkdir -p
	RM := rm -rf
	FIXPATH = $1
endif


ifeq ($(TEST_OS),3)
	ifdef ComSpec
		WINCMD:=$(ComSpec)
	endif
	ifdef COMSPEC
		WINCMD:=$(COMSPEC)
	endif

	SHELL:=$(WINCMD)
	MKD := mkdir
	RM := del /q /s
	FIXPATH = $(subst /,\,$1)
endif

ifeq ($(TEST_OS),4)
	ifdef ComSpec
		WINCMD:=$(ComSpec)
	endif
	ifdef COMSPEC
		WINCMD:=$(COMSPEC)
	endif

	SHELL:=$(WINCMD)
	MKD := "mkdir" -p
	RM := rm -rf
	FIXPATH = $1
endif

ifeq ($(TEST_OS),5)
	ifdef ComSpec
		WINCMD:=$(ComSpec)
	endif
	ifdef COMSPEC
		WINCMD:=$(COMSPEC)
	endif

	SHELL:=$(WINCMD)
	MKD := mkdir.exe -p
	RM := rm -rf
	FIXPATH = $1
endif

all: $(OBJECTS)
	gcc $^ -o $(OUTPUT_DIR)/main
$(OBJECTS): $(OUTPUT_DIR)/%.o: %.c
	$(MKD) $(call FIXPATH, $(@D))
	gcc -c -o $@ $<
clean:
	$(RM) $(call FIXPATH, $(OUTPUT_DIR))

干净环境下,使用cygwin编译

环境说明

如下所示,环境只有一个mingw32的make环境。

image-20221005110846841

使用windows下的mkdir和del操作

创建目录:MKD := mkdir

删除目录:RM := del /q /s

调整路径:FIXPATH = $(subst /,\,$1)

进行make allmake clean操作,程序都按照预期进行。

image-20221005111002220

使用linux下的mkdir和rm操作

创建目录:MKD := mkdir -p

删除目录:RM := rm -rf

调整路径:FIXPATH = $1

进行make TEST_OS=1 allmake TEST_OS=1 clean操作,程序都执行失败。mkdir失败是因为路径分隔符不对。rm是没有这个执行文件。

image-20221005111105536

总结

这些行为都是符合我预期的,一般我会通过OS判断来区分当前的系统,而后选择不同的执行命令。

image-20220927171410992

使用CDT工具链进行编译

环境搭建

到CDT的官网Eclipse Embedded CDT | Eclipse Embedded CDT (C/C++ Development Tools)™ (eclipse-embed-cdt.github.io),可以看到其有推荐windows的build tool环境:The xPack Windows Build Tools | The xPack Build Framework

直接下载就行,本地已经下载好了一份,放在路径下build-tools

环境说明

为了方便复现,执行setup.bat脚本来进行环境配置。成功配置后,where make可以看出环境是ok的。

image-20221005111349315

使用windows下的mkdir和del操作

创建目录:MKD := mkdir

删除目录:RM := del /q /s

调整路径:FIXPATH = $(subst /,\,$1)

进行make allmake clean操作,程序都报错了,可以看到这时make的SHELL已经指向了build-tools目录下的sh.exe,这时候程序已经工作在linux环境下了,不能再使用windows的mkdir/del行为了。

image-20221005112420957

使用linux下的mkdir和rm操作

创建目录:MKD := mkdir -p

删除目录:RM := rm -rf

调整路径:FIXPATH = $1

进行make TEST_OS=1 allmake TEST_OS=1 clean操作,程序都执行成功了。整个环境就是linux的环境了。

image-20221005112638507

使用linux下的mkdir和rm操作+SHELL指定为windows

创建目录:MKD := mkdir -p

删除目录:RM := rm -rf

调整路径:FIXPATH = $1

进行make TEST_OS=2 allmake TEST_OS=2 clean操作,mkdir执行失败了,rm确没报错。因为这时候rm.exe已经在build-tools有提供了,那为什么这时候没有使用build-tools目录下的mkdir.exe呢?

image-20221005112759518

使用windows下的mkdir和del操作+SHELL指定为windows

创建目录:MKD := mkdir

删除目录:RM := del /q /s

调整路径:FIXPATH = $(subst /,\,$1)

进行make TEST_OS=3 allmake TEST_OS=3 clean操作,这时候又都执行成功了。

image-20221005113203635

总结

从上面的测试程序可以看到一个情况,当使用CDT的build-tools时,程序make行为不确定了。测试程序中,我们是通过setup.bat来配置PATH参数,只影响当前编译环境,但是通常我们会直接配置系统的环境变量PATH。这时系统make环境可能就出现错乱了,本人就遇到了这个问题。

解决办法

在使用CDT工具链情况下,SHELL指定为windows时,由于这时候mkdir和windows环境的命令相同(Windows 命令 | Microsoft Learn),windows命令的优先级更高。

使用linux下的mkdir和rm操作+SHELL指定为windows+双引号

通过双引号""强制指定不使用Windows的命令,而是用build-tools中提供的mkdir.exe。由于rm没冲突,所以不需要加调整。

创建目录:MKD := "mkdir" -p

删除目录:RM := rm -rf

调整路径:FIXPATH = $1

进行make TEST_OS=4 allmake TEST_OS=4 clean操作,mkdirrm都能正常执行了。

image-20221006123002833

使用linux下的mkdir和rm操作+SHELL指定为windows+exe指定

通过.exe强制指定不使用Windows的命令,而是用build-tools中提供的mkdir.exe。由于rm没冲突,所以不需要加调整。

创建目录:MKD := mkdir.exe -p

删除目录:RM := rm -rf

调整路径:FIXPATH = $1

进行make TEST_OS=5 allmake TEST_OS=5 clean操作,mkdirrm都能正常执行了。

image-20221006123233670

总结

本质CDT提供的是linux下的build环境,当将CDT的build-tools作为默认编译环境时,就会出现make操作执行时,认为是linux环境,当想进行mkdir操作是,会和windows命令冲突,这时候如果系统中还有别的工程时,就会有冲突了。

只要理解本质原因,就可以根据各种情况针对性处理了。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages