16、Make 简介


一、Make 简介

1.1、简介

  • 编译(compile): 代码变成可执行文件,例如 gcc(C)、g++(C++)
  • 构建(build):
    • 编译众多相互关联的源码文件(且可以只对在上次编译后修改过的部分进行编译),以实现工程化的管理
    • Make 是最常用的构建工具,通常构建规则写在 Makeflie 中(要构建哪个文件、它依赖哪些源文件,当那些文件有变动时,如何重新构建它)
    • 语法:
      • make -f target -j16,其中 target 为编译目标(makefile 文件),-j16 为使用 16 线程并发进行编译
      • 若 makefile 文件名为标准文件名(Makefile、makefile 或 GNUmakefile 等),则直接执行 make -j16 即可
      • -n 参数:只显示所要执行的命令,但不会真正的执行,可用于调试
      • -s 参数:禁止所有的执行命令的显示
  • make 重新编译的原理:
    • 编译文件时 make 检查其目标文件并比较文件的更新时间戳
    • 如果源文件比目标文件具有更新的时间戳,则假定源文件已更改,那么 make 会生成新的目标文件,否则不会重新编译
  • readelf -d libxxx.so: 查看此动态库所依赖的库文件

1.2、动态库编译示例

.PHONY: clean 

# 1、指定需要生成的动态库名称,获取当前工程目录
PRJ_TARGET := libXXX.so
PRJ_ROOT := $(shell pwd)
$(info "------------PRJ_ROOT is:" $(PRJ_ROOT))


# 2、指定交叉编译器
COMPILER_PATH := /opt/cross_compile/Ambarella/cv2/linaro-aarch64-2020.09-gcc10.2-linux5.4/bin/aarch64-linux-gnu-
CC := $(COMPILER_PATH)gcc
CXX := $(COMPILER_PATH)g++
$(info "------------CXX is:" $(CXX))


# 3、指定编译选项
CFLAGS := -DFOR_AMBA_S88 -DFOR_AMBA  # 预处理选项,选择相应的芯片
CFLAGS += -O3 -Wall -fPIC  # 优化、警告及代码生成选项
CFLAGS += -mcpu=cortex-a53 -fno-aggressive-loop-optimizations -ffast-math -fpermissive # 交叉编译选项
CXXFLAGS := $(CFLAGS) -std=c++11
$(info "------------CXXFLAGS is:" $(CXXFLAGS))


# 4、指定预处理时需要的头文件选项:依赖的头文件路径
INC_DIRS := -I $(PRJ_ROOT)/SDK_DIR/include  # SDK 头文件路径
INC_DIRS += -I $(PRJ_ROOT)/SRC_DIR/include  # 源文件对应的头文件路径
INC_DIRS += -I $(PRJ_ROOT)/COMMON_DIR/include  # 公共头文件路径
INC_DIRS += -I $(PRJ_ROOT)/THIRD_PARTY_DIR/include  # 第三方库对应的头文件路径
$(info "------------INC_DIRS is:" $(INC_DIRS))


# 5、指定链接时需要的库操作选项:依赖的库文件及其路径
LDFLAGS := -ldl -lpthread # 系统库:额外需要的动态加载库及多线程库
LDFLAGS += -L $(PRJ_ROOT)/SDK_DIR/lib -lnnctrl -lvproc  # SDK 库文件及路径
LDFLAGS += -L $(PRJ_ROOT)/THIRD_PARTY_DIR/lib  -lzlog -losp -lyuv -ljsoncpp # 第三方库文件及路径(最好用静态库或者与业务版本保持一致)
$(info "------------LDFLAGS is:" $(LDFLAGS))


# 6、指定需要编译的源文件:SRC_C/SRC_CPP/SRC_CU
SRC_C := $(wildcard $(PRJ_ROOT)/SDK_DIR/source/*.c)  # SDK 中需要编译的 C 源文件
SRC_C += $(wildcard $(PRJ_ROOT)/source/*.c)  # 项目中需要编译的 C 源文件
SRC_CPP := $(wildcard $(PRJ_ROOT)/SDK_DIR/source/*.cpp)  # SDK 中需要编译的 CPP 源文件
SRC_CPP += $(wildcard $(PRJ_ROOT)/source/*.cpp) # 项目中需要编译的 CPP 源文件


# 7、指定需要链接的目标文件
PRJ_OBJS := $(patsubst %.c, %.o, $(SRC_C))
PRJ_OBJS += $(patsubst %.cpp, %.o, $(SRC_CPP))
$(info "------------OBJS is:" $(PRJ_OBJS))


# 8、链接生成动态库, $^ 表示所有依赖项(命令中的 $(PRJ_OBJS) 可以通替换为 $^),$@ 表示当前目标
$(PRJ_TARGET): $(PRJ_OBJS)
	$(CXX) -shared $(PRJ_OBJS) -o $@ $(LDFLAGS)


# 9、预处理/编译/汇编生成目标文件,$< 指代第一个前置条件 
%.o: %.c
	$(CC) -c $< -o $@ $(CFLAGS) $(INC_DIRS)
%.o: %.cpp
	$(CXX) -c $< -o $@  $(CXXFLAGS) $(INC_DIRS) 


# 10、删除可执行文件及目标文件
clean:
	rm -f $(PRJ_OBJS) $(PRJ_TARGET) 

1.3、demo 编译示例

  • 汇编 demo: -c 源文件,需指定源文件、编译选项及其依赖的头文件,得到目标文件
  • 链接 demo: 链接目标文件(.o),需指定目标文件、链接选项,此时不再需要编译选项和头文件
.PHONY: clean 

# 1、指定需要生成的动态库名称,获取当前工程目录
PRJ_TARGET := test
MAIN_CPP := test.cpp
PRJ_ROOT := $(shell pwd)
$(info "------------PRJ_ROOT is:" $(PRJ_ROOT))


# 2、指定交叉编译器
COMPILER_PATH := /opt/cross_compile/Ambarella/cv2/linaro-aarch64-2020.09-gcc10.2-linux5.4/bin/aarch64-linux-gnu-
CC = $(COMPILER_PATH)gcc
CXX = $(COMPILER_PATH)g++
$(info "------------CXX is:" $(CXX))


# 3、指定编译选项
CFLAGS := -DFOR_AMBA_S88 -DFOR_AMBA  # 预处理选项,选择相应的芯片
CFLAGS += -O3 -Wall -fPIC  # 优化、警告及代码生成选项
CFLAGS += -mcpu=cortex-a53 -fno-aggressive-loop-optimizations -ffast-math -fpermissive # 交叉编译选项
CXXFLAGS := $(CFLAGS) -std=c++11
$(info "------------CXXFLAGS is:" $(CXXFLAGS))


# 4、指定预处理时需要的头文件选项:依赖的头文件路径
INC_DIRS := -I $(PRJ_ROOT)/SRC_DIR/include  # 对外头文件路径
INC_DIRS += -I $(PRJ_ROOT)/THIRD_PARTY_DIR/include  # 第三方库对应的头文件路径,如 opencv
$(info "------------INC_DIRS is:" $(INC_DIRS))


# 5、指定链接时需要的库操作选项:依赖的库文件及其路径
LDFLAGS := -ldl -lpthread # 系统库:额外需要的动态加载库及多线程库
LDFLAGS += -L $(PRJ_ROOT)/SDK_DIR/lib -lnnctrl -lvproc  # SDK 库文件及路径
LDFLAGS += -L $(PRJ_ROOT)/THIRD_PARTY_DIR/lib -lyuv -lopencv_world # 第三方库文件及路径(最好用静态库或者与业务版本保持一致)
LDFLAGS += -L $(PRJ_ROOT)/SRC_DIR/lib -lxxx  #  对外动态库及路径
$(info "------------LDFLAGS is:" $(LDFLAGS))



# 6、链接生成可执行文件,$< 指代第一个前置条件,$@ 表示当前目标
$(PRJ_TARGET): $(PRJ_TARGET).o  # 等价于 $(TARGETS): *.o (当前目录下寻找)和 $(TARGETS): %: %.o(静态模式)
	$(CXX) $< -o $@ $(LDFLAGS)


# 7、预处理/编译/汇编生成目标文件 (根据 demo 后缀 c 或者 cpp 处理选择一个就行了),$< 指代第一个前置条件
%.o: %.c 
	$(CC) -c $< -o $@ $(CFLAGS) $(INC_DIRS)
%.o: %.cpp
	$(CXX) -c $< -o $@  $(CXXFLAGS) $(INC_DIRS) 


# 8、删除可执行文件及目标文件
clean:
	rm -f $(PRJ_TARGET).o $(PRJ_TARGET) 

二、Makefile 文件的格式

2.1、概述

  • Makefile 文件由一系列规则构成,每条规则的形式如下:
    • 第一行:冒号前面的部分,叫做目标,冒号后面的部分叫做前置条件
    • 第二行:必须由一个 tab 键开始(可以用 Notepad++ 空格转 Tab),后面跟着需要执行的命令
    • 目标是必需的,不可省略,前置条件和命令是可选的,但是两者之中必须至少存在一个
# 每条规则的格式,井号(#)在 Makefile 中表示注释
<target>: <prerequisites> 
[tab]  <commands>
# 依赖文件 prerequisite 的搜索路径,可以通过 VPATH 指定,它是 make 的一个特殊变量
# VPATH = src:../headers, 不同路径目录用冒号:隔开
# 如果没有指明这个变量,make 只会在当前的目录中去找寻依赖文件和目标文件
# 如果定义了这个变量,那么,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件

# eg:
c.txt: a.txt b.txt
    cat a.txt b.txt > c.txt
    


# 静态模式:是一种自动编译模式,在这种模式下,我们可以容易的定义“多目标”规则,让我们的规则变得更加有弹性和灵活
<targets ...> : <target-pattern> : <prereq-patterns ...>
[tab]    <commands>
# targets:定义了一些列的目标文件,也就是多目标,可以有通配符,是目标的一个集合。
# target-pattern:targets 的模式,也就是目标集模式
# prereq-patterns:目标的依赖模式,它根据目标集模式获取目标文件名(不带后缀),然后结合依赖模式得到最终的依赖目标文件名
# 注意:我们的 “目标模式” 或是 “依赖模式” 中都应该有 % 这个字符


# 静态模式举例: 遍历所有的 .c 文件,对所有的 .c 文件进行编译,然后编译生成对应的 .o 文件
$(OBJS): %.o: %.c  # % 代表取去掉 .o 后的文件名
    gcc -c $< -o $@

# OBJS:这个 OBJS 就是各种 .o 文件的集合
# %.o:目标集模式,表示我们的 target 集合中都是以 .o 结尾的
# %.c:对 target-parrtern 所形成的目标集进行二次定义,取<target-parrtern>模式中的 % (也就是去掉了 .o 这个结尾)
# 并为其加上 .c 这个结尾,形成的新集合,而我们在实际编写程序时,targets 是不需要的,可以简写如下:
%.o: %.c
    gcc -c $< -o $@


$(OBJ): %: %.o  
# 第一个 % 代表目标集模式:OBJ 中的所有文件都不带后缀
# 第二个 %.o 根据目标集模式获取目标文件名(不带后缀),然后结合依赖模式得到最终的依赖目标文件名

2.2、目标(target)

  • 目标: 一个目标就构成一条规则,目标通常是需要构建对象的文件名(可以是多个)
  • 伪目标: 可以不是文件名,而是某个操作的名字(它并不会创建目标文件,只是想去执行这个目标下面的命令
# 伪目标:删除对象文件,常见的有 all、install、clean
.PHONY: clean # 告诉 make 这个不是真正意义上的 target,make 不需要自动生成依赖关系和推导规则
clean:
	rm *.o

# 终端执行命令
make -f makefile clean

# 常见的伪目标命令
# make all: It compiles everything so that you can do local testing before installing applications.
# make install:It installs applications at right places.
# make clean:It cleans applications, gets rid of the executables, any temporary files, object files, etc

2.3、前置条件(prerequisites)

  • 前置条件通常是一组文件名,之间用 空格分隔 ;若目标后面没有前置条件,意味着它跟其他文件都无关
  • 前置条件指定了 目标 是否重新构建的判断标准:只要有一个前置文件不存在,或者有过更新,目标就需要重新构建

2.4、命令(commands)

  • 构建目标的具体指令,它的运行结果通常就是 生成目标文件
  • 指令:由 一行或多行的 Shell 命令 组成,每行命令在一个单独的 shell 中执行(不同的进程中执行
  • Note:每行命令之前必须有一个 tab 键;命令的前面加上@,可以关闭屏幕打印当前命令或注释
# 取不到 foo 的值,因为两行命令在两个不同的进程执行
var-lost:
    export foo=bar
    echo "foo=[$$foo]"

# 解决办法 1:两行命令写在一行,中间用分号分隔
var-kept:
    export foo=bar; echo "foo=[$$foo]"

# 解决办法 2:加换行符
var-kept:
    export foo=bar; \
    echo "foo=[$$foo]"

# 解决办法 3:加 .ONESHELL: 命令
.ONESHELL:
var-kept:
    export foo=bar; 
    echo "foo=[$$foo]"

# 关闭屏幕命令输出
all:
    @# 这是测试
    @echo TODO

三、Makefile 文件的语法

3.1、通配符和模式匹配

  • Makefile 可以使用 shell 命令,所有 shell 支持的通配符在 Makefile 中也是同样适用的
  • Makefile 的通配符与 Bash Shell 一致,主要有星号*(匹配0个或者是任意个字符)、问号?(匹配任意一个字符)和中括号[] (需要匹配的字符放在中括号里),eg: *.o 表示所有后缀名为 o 的文件
  • Make 命令允许对文件名进行类似正则运算的匹配,主要用到的匹配符是 %(取出文件的文件名,但不包含后缀)
# 假定当前目录下有 f1.c 和 f2.c 两个源码文件,需要将它们编译为对应的对象文件
%.o: %.c

# 等同于下面的写法,使用匹配符 %,可以将大量同类型的文件,只用一条规则就完成构建
f1.o: f1.c
f2.o: f2.c

3.2、变量赋值运算符

(1)递归赋值/延迟赋值(=)
# 在执行时扩展,允许递归扩展,可能影响多个变量,所有目标变量相关的其他变量都受影响
VARIABLE = value  # (可以是多个值,以空格分隔,value1 value2 value3 ...)

# eg:
x = foo    # 在执行时扩展
y = $(x)b  # 在执行时扩展
x = new    # 在执行时扩展

test:
      @echo "y=>$(y)"
      @echo "x=>$(x)"
   
# 执行 make test 后,输出如下:
y=>newb
x=>new
(2)立即赋值(:=)
# 在定义时扩展,只对当前语句的变量有效
VARIABLE := value

# eg:
x := foo    # 在定义时扩展
y := $(x)b  # 在定义时扩展
x := new    # 在定义时扩展

test:
      @echo "y=>$(y)"
      @echo "x=>$(x)"
   
# 执行 make test 后,输出如下:
y=>foob
x=>new
(3)追加赋值(+=)
# 将值追加到变量的尾端(用空格隔开)
VARIABLE += value


x := foo
y := $(x)b
x += $(y)

test:
      @echo "y=>$(y)"
      @echo "x=>$(x)"
      
# 执行 make test 后,输出如下:
y=>foob
x=>foo foob
(4)条件赋值(?=)
# 只有在该变量为空时才设置值
VARIABLE ?= value

x := foo
y := $(x)b
x ?= new

test:
      @echo "y=>$(y)"
      @echo "x=>$(x)"

# 执行 make test 后,输出如下:
y=>foob
x=>foo

3.3、宏定义(变量替换)

宏在 Makefile 中使用 名称 = 值 的形式来定义

a、特殊的宏
  • $@:make 命令当前构建的那个目标,即每条规则中 target 的名字
  • $?:the names of the changed dependents,代表前置条件中所有已修改的源文件
  • $<:the name of the related file that caused the action,通常指代第一个前置条件,比如,规则为 t: p1 p2,那么$< 就指代p1
  • $*:the prefix shared by target and dependent files,通常指代匹配符 % 匹配的部分, 比如 % 匹配 f1.txt 中的 f1 ,$* 就表示 f1
  • $^:指代所有前置条件,比如,规则为 t: p1 p2,那么 $^ 就指代 p1 p2
# $@ represents hello and $? or $@.cpp picks up all the changed source files
hello: main.cpp hello.cpp factorial.cpp
   $(CC) $(CFLAGS) $? $(LDFLAGS) -o $@

# 等同于下面的写法
hello: main.cpp hello.cpp factorial.cpp
   $(CC) $(CFLAGS) $@.cpp $(LDFLAGS) -o $@


# $< 的用法
a.txt: b.txt c.txt
    cp $< $@

# 等同于下面的写法
a.txt: b.txt c.txt
    cp b.txt a.txt 
b、常规宏
  • CC:编译 C 语言文件的程序,默认是 cc
  • CXX:编译 C++ 文件的程序,默认是 g++
  • CPP:运行 C 预处理器并输出到当前输出流的程序,默认是 $(CC) -E
  • PWD:获取当前路径
  • LD_LIBRARY_PATH:是 Linux 环境变量名,该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径
    • 临时修改:export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:$LD_LIBRARY_PATH
    • 永久生效:可用 vim /etc/profile ,修改其中的 LD_LIBRARY_PATH 变量
    • LIBRARY_PATH is used by gcc before compilation to search for directories containing libraries that need to be linked to your program
    • LD_LIBRARY_PATH is used by your program to search for directories containing the libraries after it has been successfully compiled and linked
  • 常见宏变量的附加参数:
    • CFLAGS:传递给 C 编译器的额外 flag
    • CXXFLAGS:传递给 C++ 编译器的额外 flag
    • LDFLAGS:Extra flags to give to compilers when they are supposed to invoke the linker, ld
    • CPPFLAGS:Extra flags to give to the C preprocessor and programs, which use it

3.4、Makefile 条件判断

# 1、条件判断关键字
- ifeq:判断参数是否不相等,相等为 true,不相等为 false。
- ifneq:判断参数是否不相等,不相等为 true,相等为 false。
- ifdef:判断是否有值,有值为 true,没有值为 false。
- ifndef:判断是否有值,没有值为 true,有值为 false。
- endif:结束判断


# 2、条件判断使用方式
ifeq (ARG1, ARG2) or ifeq 'ARG1' 'ARG2' or ifeq "ARG1" "ARG2"
ifdef VARIABLE_NAME


# 3、条件判断使用示例
ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
   ifeq ($(APP_STL), c++_shared)
      SNPE_LIB_DIR := $(SNPE_ROOT)/lib/aarch64-android-clang6.0
   else
      $(error Unsupported APP_STL: '$(APP_STL)')
   endif
else ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
   ifeq ($(APP_STL), c++_shared)
      SNPE_LIB_DIR := $(SNPE_ROOT)/lib/arm-android-clang6.0
   else
      $(error Unsupported APP_STL: '$(APP_STL)')
   endif
else
   $(error Unsupported TARGET_ARCH_ABI: '$(TARGET_ARCH_ABI)')
endif

3.5、Makefile 添加打印

# 直接添加方式
$(warning "this is test========================")
$(info $(KBUILD_CFLAGS))
$(error $(KBUILD_CFLAGS))

# 使用 echo 命令打印,执行 make test 即可打印 echo 内容
test:
	@echo $(KBUILD_CFLAGS)

四、Makefile 常用函数

  • wildcard:扩展通配符函数,src=$(wildcard *.c),匹配所有 .c 文件,列表赋值给 src,保留了路径
  • patsubst:替换通配符函数,obj=$(patsubst %.c, %.o, $(wildcard *.c)),将最后一个参数扩展后的 .c 文件替换成 .o
  • notdir:取文件名函数(去掉目标的路径),filename=$(notdir $(wildcard ./sub/*.c)),去除掉 ./sub/ 路径,只保留源代码名称
  • dir:取文件目录函数(去掉文件名),dir=$(dir src/foo.c hacks),去除掉源代码名称,只保留目录,得到src/ ./
  • 其它函数:去空格函数 strip、过滤函数 filter、反过滤函数 filter-out、排序函数 sort、取后缀函数 suffix、取前缀函数 basename
src=$(wildcard *.c ./sub/*.c)  # 使用 wildcard 函数后,引用变量时,会自动帮我们展开
filename=$(notdir $(src))
obj=$(patsubst %.c, %.o, $(filename))

all:
	@echo $(src)  # 注意 TAB 键,@echo 和 echo 的区别,前者会隐藏命令,后者会输出命令

tdir:
	@echo $(filename)

tobj:
	@echo $(obj)

在这里插入图片描述


五、参考资料

1、Make 命令教程
2、Makefile 基础教程
3、跟我一起写Makefile
4、Makefile中的 patsubst 和 wildcard 函数

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
过程: 1.在虚拟机上安装了vmware,安装完成后,默认vm tools是没有安装的,启动后在下方提示没有安装虚拟工具,安装过程省略; 2.安装redhat,这个安装过程就省略,没安过的可以也去G一下; 3.安装vm tools: 1)以ROOT身份进入LINUX 2)按下 CTRL ALT组合键,进入主操作系统,点击VMWARE状态栏安装提示,或者点击 虚拟菜单下的安装虚拟机工具子菜单. 3)确认安装VMWARE TOOLS.   这时我们并没有真正的安装上了VMWARE TOOLS软件包,如果您点击菜单:DEVICES,您就会发现光驱的菜单文字变为:ide1:0-> C:\Program Files\VMware\VMware Workstation\Programs\linux.iso,这表示VMWARE将LINUX的ISO映象文件作为了虚拟机的光盘 4)鼠标点击LINUX界面,进入LINUX. 5)运行如下命令,注意大小写. mount -t iso9660 /dev/cdrom /mnt 加载CDROM设备,这时如果进入 /mnt 目录下,你将会 发现多了一个文件:vmware-linux-tools.tar.gz.这就是WMWARE TOOLS的LINUX软件包,也就是我们刚才使用WINISO 打开LINUX.ISO文件所看到的.   cp /mnt/vmware-linux-tools.tar.gz /tmp   将该软件包拷贝到LINUX的 TMP目录下.   umount /dev/cdrom   卸载CDROM.   cd /tmp   进入TMP目录   tar zxf vmware-linux-tools.tar.gz   解压缩该软件包,默认解压到vmware-tools-distrib 目录下(与文件名同名).   cd vmware-linux-tools   进入解压后的目录 这时要进入文本模式下运行下面的命令   ./install.pl 这时install提示你是否需要备份以前的配置文件,建议选择"y".   等待INSTALL运行完成后,这时键入 STARTX 命令,启动LINUX图形界面,vm中不再提示没有安装虚拟机工具了 在Ubuntu下安装VMware-Tools不像在Windows下安装容易,昨晚整了挺长时间终于安上了.方法在下面. 感谢提供方法的大侠! VMware Tools位置:VMware的安装路径\VMware\VMware Workstation\linux.iso 启动后按Esc选择recovery mode登陆.然后点击"虚拟机"→"安装VMware Tools". [root@rd01 ~]# mount /cdrom # 有时可能加载不了,这时就要先将系统关闭,再手动指定 ISO 映像: [root@rd01 ~]# cd /cdrom [root@rd01 ~]# ls -a [root@rd01 ~]# cp VMwareTools-5.5.1-19175.tar.gz /tmp [root@rd01 ~]# cd /tmp [root@rd01 ~]# tar zxpf VMwareTools-5.5.1-19175.tar.gz [root@rd01 ~]# cd vmware-tools-distrib [root@rd01 vmware-tools-distrib]# ./vmware-install.pl Creating a new installer database using the tar3 format. Installing the content of the package. # 安装过程的画面,全部使用默认值,一直按 Enter 就对了 In which directory do you want to install the binary files? [/usr/bin] What is the directory that contains the init directories (rc0.d/ to rc6.d/)? [/etc/rc.d] What is the directory that contains the init scripts? [/etc/rc.d/init.d] In which directory do you want to install the daemon files? [/usr/sbin] In which directory do you want to install the library files? [/usr/lib/vmware-tools] Thepath "/usr/lib/vmware-tools" does not exist currently. This programisgoingto create it, including needed parent directories. Is thiswhatyou want? [yes] In which directory do you want to install the documentation files? [/usr/share/doc/vmware-tools] Thepath "/usr/share/doc/vmware-tools" does not exist currently.Thisprogram isgoing to create it, including needed parent directories.Isthis what you want? [yes] The installation of VMware Tools 5.5.1 build-19175 for Linux completed successfully. You can decide to remove this software from your system at any time by invoking the following command: "/usr/bin/vmware-uninstall-tools.pl". Before running VMware Tools for the first time, you need to configure it by invoking the following command: "/usr/bin/vmware-config-tools.pl". Do you want this program to invoke the command for you now? [yes] Stopping VMware Tools services in the virtual machine: Guest operating system daemon: [ 确定 ] Trying to find a suitable vmhgfs module for your running kernel. The module bld-2.6.9-5.EL-i686-RHEL4 loads perfectly in the running kernel. pcnet32 30153 0 Unloading pcnet32 module Trying to find a suitable vmxnet module for your running kernel. The module bld-2.6.9-5.EL-i686-RHEL4 loads perfectly in the running kernel. Detected X.org version 6.8. 关闭控制台鼠标服务: [ 确定 ] 启动控制台鼠标服务: [ 确定 ] Please choose one of the following display sizes (1 - 13): # 显示分辨率,这里是以 1024x768 为例 # VMware Tools 安装的时候,会自动修改 X server 的配置文件 [1] "640x480" [2]< "800x600" [3] "1024x768" [4] "1152x864" [5] "1280x800" [6] "1152x900" [7] "1280x1024" [8] "1376x1032" [9] "1400x1050" [10] "1680x1050" [11] "1600x1200" [12] "1920x1200" [13] "2364x1773" Please enter a number between 1 and 13: [2] 3 X Window System Version 6.8.2 Release Date: 9 February 2005 X Protocol Version 11, Revision 0, Release 6.8.2 Build Operating System: Linux 2.6.9-34.EL i686 [ELF] Current Operating System: Linux rd01.domain 2.6.9-34.EL #1 Wed Mar 8 00:07:35 CST 2006 i686 Build Date: 04 May 2006 Build Host: x8664-build.centos.org Before reporting problems, check http://wiki.X.Org to make sure that you have the latest version. Module Loader present OSKernel: Linux version 2.6.9-34.EL (buildcentos@build-i386) (gccversion3.4.5 20051201 (Red Hat 3.4.5-2)) #1 Wed Mar 8 00:07:35 CST 2006P Markers: (--) probed, (**) from config file, (==) default setting, ( ) from command line, (!!) notice, (II) informational, (WW) warning, (EE) error, (NI) not implemented, (??) unknown. ( ) Log file: "/tmp/vmware-config0/XF86ConfigLog.3131", Time: Mon Jun 12 20:57:34 2006 ( ) Using config file: "/tmp/vmware-config0/XF86Config.3131" (WW) VMWARE(0): Failed to set up write-combining range (0xf0000000,0x1000000) X is running fine with the new config file. Starting VMware Tools services in the virtual machine: Switching to guest configuration: [ 确定 ] Guest filesystem driver: [ 确定 ] DMA setup: [ 确定 ] Guest operating system daemon: [ 确定 ] The configuration of VMware Tools 5.5.1 build-19175 for Linux for this running kernel completed successfully. You must restart your X session before any mouse or graphics changes take effect. You can now run VMware Tools by invoking the following command: "/usr/bin/vmware-toolbox" during an XFree86 session. To use the vmxnet driver, restart networking using the following commands: /etc/init.d/network stop rmmod pcnet32 rmmod vmxnet depmod -a modprobe vmxnet /etc/init.d/network start Enjoy, --the VMware team [root@rd01 vmware-tools-distrib]# shutdown -r now # 修改完成之后,重新启动计算机,让 VMware Tools 生效. == 重启后,你可能会发现还是要按"Ctrl Alt"释放鼠标(VM6.0没这问题了),我用的是5.5.3,要手动执行才有效果. 通过终端运行VMware-Tools: 点击Ubuntu桌面左上角的Applications→附件→终端,会打开一个类似Windows中记事本的程序,在里面输入以下内容($是自带的,不用专门输入): $ /usr/bin/vmware-toolbox 但如果你嫌麻烦,我们就需要让vmware-toolbox实现开机自动运行.点击 Ubuntu菜单:System→首选项→会话→Startup Programs,Add一个Name叫"vmware-toolbox",Command是"/usr/bin/vmware-toolbox"的启动 程序.这样每次开机后就能自动运行VMware Tools了.重启Ubuntu看看效果吧!(注意:vmware-toolbox并不是在后台隐藏运行的,启动后不要关闭). VMware Tools固然是个好东西,但也有副作用,比如说:虚拟机中的鼠标的滚轮不好使了.我们这样解决这个问题,还是打开终端,输入: $ sudo gedit /etc/X11/xorg.conf 这个命令使系统以root权限打开鼠标配置文件/etc/X11/xorg.conf.把文件中的 Option "Protocol" "ps/2" 改成 Option "Protocol" "IMPS/2" 重启Ubuntu搞定
### 回答1: invoking make -j16 -l16 failed 的意思是“调用 make -j16 -l16 失败”。make 是一个常用的编译工具,-j16 表示使用 16 个线程进行编译,-l16 表示限制系统负载为 16。如果调用失败,可能是因为系统资源不足或者命令输入有误等原因。 ### 回答2: 当我们在使用make命令时,希望加快编译速度,就可以使用“-j”选项来指定并发编译的任务数。例如“-j16”表示同时开启16个任务进行编译。而“-l”选项则是用来设置系统负载的最大值,表示当系统负载达到该值时,make就会暂停一段时间等待系统负载下降再继续编译。例如“-l16”表示当系统负载达到16时,make就会暂停编译。 当执行“make -j16 -l16”命令时,如果出现“invoking make -j16 -l16 failed”的错误提示,说明并发编译或系统负载控制失败,则需要进行一些排查和解决: 1. 检查系统资源是否足够,如CPU、内存、磁盘空间等是否充足。 2. 检查系统负载情况,使用“top”或“uptime”命令查看当前系统负载,如果负载已经很高,可以等待一段时间再执行make命令。 3. 如果系统资源足够,但仍出现错误,一般是由于并发编译任务之间的依赖关系没有明确指定或者存在竞争条件,可以尝试降低“-j”选项的值,如使用“-j8”或“-j4”等。 4. 如果仍然无法解决问题,则需要检查Makefile文件中的相关配置是否正确或者与所使用的编译器版本是否兼容等问题。 总之,在使用make命令时,需要根据实际情况选择合适的并发编译任务数和最大系统负载,并进行一些排查和调试,才能保证编译的成功。 ### 回答3: 在使用make命令执行编译任务时,可能会遇到“invoking make -j16 -l16 failed”这样的错误提示。这个错误通常是由于make命令执行时出现了问题,导致编译任务无法完成。 首先,我们需要了解make命令的作用。make命令是一个编译工具,可以自动化地执行编译任务,根据编译规则生成目标文件。通常在Linux下编译程序时,可以使用make命令进行自动化编译。 在这个错误提示中,-j16和-l16make命令的参数。-j参数用于指定同时执行的任务数,这里指定是16个。-l参数用于限制make命令的负载,避免过度使用系统资源,这里指定是16。 如果make命令无法执行任务,就会出现“invoking make -j16 -l16 failed”这样的错误提示。这个错误的原因可能是多方面的,例如编译环境不全、依赖库缺失、语法错误等等。 为了解决这个错误,我们可以采取以下几个方法: 1.检查编译环境配置是否正确,例如编译器、makefile、环境变量等。 2.检查依赖库是否缺失,查看错误提示中是否有关于缺失库的信息。 3.检查代码语法是否正确,是否存在语法错误或语义错误。 4.尝试更改make命令的参数,例如降低-j参数和-l参数的值,以避免过度使用系统资源。 5.查阅相关资料,寻找解决该问题的方法或技巧。 总之,遇到“invoking make -j16 -l16 failed”这样的错误提示,需要我们认真分析错误原因,采取合适的解决方法,最终才能成功地完成程序的编译。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值