patsubst如何读(spat怎么读音)
makefile当中foreach能不能和patsubst一起使用
makefile当中foreach能不能和patsubst一起使用
不是,这个只是做字符串转换,比方说你在makefile里定义了所有要编译的源文件
SRCC = a.c b.c c.c
那么你可以用 patsubst 这个函数来将 SRCC 里存放的源文件名字转换成对应的目标文件名,
OBJS = $(patsubst %.c, %.o, $(SRCC))
此时 OBJS 的内容就是 a.o b.o c.o
在linux下如果有多个文件和头文件如何来编写make,只要执行make就可以编译了,谢谢了
#----------------------------------------------------------------------------
# Macros
#----------------------------------------------------------------------------
CC = gcc
CXX = g++
LD = $(CXX) $(CCFLAGS) $(CPPFLAGS)
AR = ar
PICFLAGS = -fPIC
CPPFLAGS = $(PICFLAGS) $(GENFLAGS) -D_REENTRANT
OBJEXT = .o
OUTPUT_OPTION = -o "../build/x86/$@"
OUTPUTBIN_OPTION = -o "../bin/$@"
COMPILE.c = $(CC) $(CFLAGS) $(CCFLAGS) $(CPPFLAGS) -c
COMPILE.cc = $(CXX) $(CCFLAGS) $(CPPFLAGS) -c
LDFLAGS = -L"../lib" -L"../lib/realse"
CCC = $(CXX)
MAKEFILE = Makefile.x86_EmbedTask
DEPENDENCIES = .depend.$(MAKEFILE)
BTARGETDIR = ./
BIN = $(BTARGETDIR)x86EmbedTask$(EXESUFFIX)$(EXEEXT)
CAT = cat
MV = mv -f
RM = rm -rf
CP = cp -p
NUL = /dev/null
MKDIR = mkdir -p
TESTDIRSTART = test -d
TESTDIREND = ||
TOUCH = touch
EXEEXT =
LIBPREFIX = lib
LIBSUFFIX =
GENFLAGS = -O
OPH = ../build/x86/
OBJS = $(OPH)Mtask$(OBJEXT) $(OPH)ServerConnectPool$(OBJEXT)
OBJS1 = Mtask$(OBJEXT) ServerConnectPool$(OBJEXT)
SRC = Mtask.cpp ServerConnectPool.cpp
LINK.cc = $(LD) $(LDFLAGS)
STATICFLAGS = -DACE_AS_STATIC_LIBS
EXPORTFLAGS =
#----------------------------------------------------------------------------
# Local targets
#----------------------------------------------------------------------------
all: $(BIN)
$(BIN): $(OBJS1)
@$(TESTDIRSTART) "$(BTARGETDIR)" $(TESTDIREND) $(MKDIR) "$(BTARGETDIR)"
$(LINK.cc) $(OBJS) $(LDLIBS) $(OUTPUTBIN_OPTION)
SPACE = $(should_be_unset) $(should_be_unset)
GENERATED_DIRTY =
.PRECIOUS: $(GENERATED_DIRTY)
$(OBJS): $(GENERATED_DIRTY)
generated: $(GENERATED_DIRTY)
@-:
Mtask$(OBJEXT): Mtask.cpp
$(COMPILE.cc) $(EXPORTFLAGS) $(OUTPUT_OPTION) Mtask.cpp
ServerConnectPool$(OBJEXT): ServerConnectPool.cpp
$(COMPILE.cc) $(EXPORTFLAGS) $(OUTPUT_OPTION) ServerConnectPool.cpp
clean:
-$(RM) $(OBJS)
realclean: clean
-$(RM) $(BIN)
-$(RM) $(GENERATED_DIRTY)
#----------------------------------------------------------------------------
# Dependencies
#----------------------------------------------------------------------------
#
#$(DEPENDENCIES):
# @$(TOUCH) $(DEPENDENCIES)
#
#depend:
# -$(MPC_ROOT)/depgen.pl $(CFLAGS) $(CCFLAGS) $(CPPFLAGS) -f $(DEPENDENCIES) $(SRC) 2 $(NUL)
#
#include $(DEPENDENCIES)
按照这个makefile进行相应的修改,即可实现只要执行make就可以编译了.
如何调试makefile
makefile 的调试有点像魔法。可惜,并不存在makefile 调试器之类的东西可用来查看特定规则是如何被求值的,或某个变量是如何被扩展的。相反,大部分的调试过程只是在执
行输出的动作以及查看makefile。事实上,GNU make 提供了若干可以协助调试的内置函数以及命令行选项。
用来调试makefile 的一个最好方法就是加入调试挂钩以及使用具保护的编程技术,让你能够在事情出错时恢复原状。我将会介绍若干基本的调试技术以及我所发现的最有用的具保
护能力的编码习惯。
1.make 的调试功能
warning函数非常适合用来调试难以捉摸的makefile。因为warning函数会被扩展成空字符串,所以它可以放在makefile 中的任何地方:开始的位置、工作目标或必要条件列表中以
及命令脚本中。这让你能够在最方便查看变量的地方输出变量的值。例如:
$(warning A top-level warning)
FOO := $(warning Right-hand side of a simple variable)bar
BAZ = $(warning Right-hand side of a recursive variable)boo
$(warning A target)target: $(warning In a prerequisite list)makefile
$(BAZ)
$(warning In a command script)
ls
$(BAZ):
这会产生如下的输出:
$ make
makefile:1: A top-level warning
makefile:2: Right-hand side of a simple variable
makefile:5: A target
makefile:5: In a prerequisite list
makefile:5: Right-hand side of a recursive variable
makefile:8: Right-hand side of a recursive variable
makefile:6: In a command script
ls
makefile
请注意,warning函数的求值方式是按照make标准的立即和延后求值算法。虽然对BAZ的赋值动作中包含了一个warning函数,但是直到BAZ在必要条件列表中被求值后,这个信息才
会被输出来。
“可以在任何地方安插warning调用”的这个特性,让它能够成为一个基本的调试工具。
2.命令行选项
我找到了三个最适合用来调试的命令行选项:
--just-print(-n)
--print-database(-p)
--warn-undefined-variables。
2.1 --just-print
在一个新的makefile 工作目标上,我所做的第一个测试就是以--just-print(-n)选项来调用make。这会使得make读进makefile并且输出它更新工作目标时将会执行的命令,但是
不会真的执行它们。GNU make 有一个方便的功能,就是允许你为将被输出的命令标上安静模式修饰符(@)。
这个选项被假设可以抑制所有命令的执行动作,然而这只在特定的状况下为真。实际上,你必须小心以对。尽管make不会运行命令脚本,但是在立即的语境之中,它会对shell函数
调用进行求值动作。例如:
REQUIRED_DIRS = ...
_MKDIRS := $(shell for d in $(REQUIRED_DIRS); \
do \
[[ -d $$d ]] || mkdir -p $$d; \
done)
$(objects) : $(sources)
正如我们之前所见,_MKDIRS 简单变量的目的是触发必要目录的创建动作。如果这个makefile 是以--just-print 选项的方式运行的,那么当make 读进makefile 时,shell命令将
会一如往常般被执行。然后,make 将会输出(但不会执行)更新$(objects)文件列表所需要进行的每个编译命令。
2.2 --print-data-base
--print-data-base(-p)是另一个你常会用到的选项。它会运行makefile,显示GNU版权信息以及make 所运行的命令,然后输出它的内部数据库。数据库里的数据将会依种类划分
成以下几个组:variables、directories、implicit rules、pattern-specific variables、files(explicit rules)以及vpath earch path。如下所示:
# GNU Make 3.80
# Copyright (C) 2002 Free Software Foundation, Inc.
# This is free software; see the source for copying conditions.
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
正常的命令将会在此处执行
# Make data base, printed on Thu Apr 29 20:58:13 2004
# Variables
...
# Directories
...
# Implicit Rules
...
# Pattern-specific variable values
...
# Files
...
# VPATH Search Paths
让我们更详细地查看以上这几个区段。
变量区段(variable)将会列出每个变量以及具描述性的注释:
# automatic
D = $(patsubst %/,%,$(dir $))
# environment
EMACS_DIR = C:/usr/emacs-21.3.50.7
# default
CWEAVE = cweave
# makefile (from `../mp3_player/makefile', line 35)
CPPFLAGS = $(addprefix -I ,$(include_dirs))
# makefile (from `../ch07-separate-binaries/makefile', line 44)
RM := rm -f
# makefile (from `../mp3_player/makefile', line 14)
define make-library
libraries += $1
sources += $2
$1: $(call source-to-object,$2)
$(AR) $(ARFLAGS) $$@ $$^
endef
自动变量不会被显示出来,但是通过它们可以方便变量的获得,像$(D)。注释所指出的是origin 函数所返回的变量类型(参见“较不重要的杂项函数”一节)。如果变量被定义
在一个文件中,则会在注释中指出其文件名以及该定义所在的行号。简单变量和递归变量的差别在于赋值运算符。简单变量的值将会被显示成右边部分被求值的形式。
下一个区段标示为Directories,它对make 开发人员比对make 用户有用。它列出了将会被make 检查的目录,包括可能会存在的SCCS 和RCS 子目录,但它们通常不存在。对每个目
录来说,make 会显示实现细节,比如设备编号、inode 以及文件名模式匹配的统计数据。
接着是Implicit Rules 区段。这个区段包含了make 数据库中所有的内置的和用户自定义的模式规则。此外,对于那些定义在文件中的规则,它们的注释将会指出文件名以及行号
:
%.c %.h: %.y
# commands to execute (from `../mp3_player/makefile', line 73):
$(YACC.y) --defines $
$(MV) y.tab.c $*.c
$(MV) y.tab.h $*.h
%: %.c
# commands to execute (built-in):
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
%.o: %.c
# commands to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $
查看这个区段,是让你能够熟悉make 内置规则的变化和结构的最佳方法。当然,并非所有的内置规则都会被实现成模式规则。如果你没有找到你想要的规则,可以查看Files区段
,旧式后缀规则就列在该处。
下一个区段被标示为Pattern-specific variables,此处所列出的是定义在makefile 里的模式专属变量。所谓模式专属变量,就是变量定义的有效范围被限定在相关的模式规则执
行的时候。例如,模式变量YYLEXFLAG 被定义成:
%.c %.h: YYLEXFLAG := -d
%.c %.h: %.y
$(YACC.y) --defines $
$(MV) y.tab.c $*.c
$(MV) y.tab.h $*.h
将会被显示成:
# Pattern-specific variable values
%.c :
# makefile (from `Makefile', line 1)
# YYLEXFLAG := -d
# variable set hash-table stats:
# Load=1/16=6%, Rehash=0, Collisions=0/1=0%
%.h :
# makefile (from `Makefile', line 1)
# YYLEXFLAG := -d
# variable set hash-table stats:
# Load=1/16=6%, Rehash=0, Collisions=0/1=0%
# 2 pattern-specific variable values
接着是Files 区段,此处所列出的都是与特定文件有关的自定义和后缀规则:
# Not a target:
.p.o:
# Implicit rule search has not been done.
# Modification time never checked.
# File has not been updated.
# commands to execute (built-in):
$(COMPILE.p) $(OUTPUT_OPTION) $
lib/ui/libui.a: lib/ui/ui.o
# Implicit rule search has not been done.
# Last modified 2004-04-01 22:04:09.515625
# File has been updated.
# Successfully updated.
# commands to execute (from `../mp3_player/lib/ui/module.mk', line 3):
ar rv $@ $^
lib/codec/codec.o: ../mp3_player/lib/codec/codec.c ../mp3_player/lib/codec/codec.c ../mp3_player/include/codec/codec.h
# Implicit rule search has been done.
# Implicit/static pattern stem: `lib/codec/codec'
# Last modified 2004-04-01 22:04:08.40625
# File has been updated.
# Successfully updated.
# commands to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $
Linux下 Makefile中的 patsubst 的问题!!!!!!!高手快来
不是,这个只是做字符串转换,比方说你在makefile里定义了所有要编译的源文件
SRCC
=
a.c
b.c
c.c
那么你可以用
patsubst
这个函数来将
SRCC
里存放的源文件名字转换成对应的目标文件名,
OBJS
=
$(patsubst
%.c,
%.o,
$(SRCC))
此时
OBJS
的内容就是
a.o
b.o
c.o
如何编译预置obj 文件
1. 如何在preloader 中预置obj 文件?
Branch: GB, GB2, ICS, ICS2, JB, JB2
Step1. 首先获取obj 文件,如果是preloader 已有的Source code 需要预置为obj 文
件,那么可到如下路径获取obj 文件:mediatek/[source]/preloader/out
Step2. 在mediatek/[source]/preloader 目录下创建文件夹:myobjs,将Step1 中获取
的obj 文件放到该文件夹中
Step3. 修改mediatek/[source]/preloader/Makefile 文件,在该文件如下Code:
$(D_BIN)/$(PL_IMAGE_NAME).elf:
之前添加:
MYOBJS := $(D_ROOT)/myobj
Step4. 修改mediatek/[source]/preloader/Makefile 中$(D_BIN)/$(PL_IMAGE_NAME).elf
生成命令,将MYOBJS 加入:如下:
$(D_BIN)/$(PL_IMAGE_NAME).elf:
$(LD) --gc-sections -Bstatic -T$(MTK_PATH_PLATFORM)/link_descriptor.ld \
$(wildcard $(D_OBJ)/*) $(wildcard $(MYOBJS)/*) $(SECURITY_LIB) -Map
system.map -o $(D_BIN)/$(PL_IMAGE_NAME).elf
Step5. 如果添加的obj 文件在preloader 中有对应的Source code,还需要修改
Source code 对应的make File 文件,将该Source code 从make File 文件中删除,以
bmt.c 为例,需要修改medaitek/platform/$platform/preloader/src/drivers/makefile,
将bmt.c 从该文件的MOD_SRC 中删除
说明:preloader 的Source code 位于如下路径:
– mediatek/platform/$platform/preloader/
– mediatek/custom/$platform/preloader/
– mediatek/custom/common/preloader/
– mediatek/custom/$porject/preloader/
2. 如何在uboot 中预置obj 文件?
Branch: GB, GB2, ICS, ICS2
Case1. 该obj 文件是从第三方处获取,在codebase 原本不存在.c 文件,不需要编
译进某个lib 文件
Step1. 首先获取obj 文件
Step2. 在bootable/bootloader/uboot 目录下添加myobjs 文件夹,将Step1 中获取的
obj 文件放到该文件夹中
Step3. 修改bootable/bootloader/uboot/Makefile,在该文件如下Code:
GEN_UBOOT = \
之前添加:
MYCUSTOMOBJS := $(wildcard myobjs/*)
MEDIATEK CONFIDENTIAL
FOR zhanghui@ vanzotec.com USE ONLY
loginid=zhanghui@vanzotec.com,time=2013-10-08 19:27:59,ip=180.166.121.198,doctitle=如何在preloader、uboot、lk、kernel中预置obj文件.docx,company=Vanzo_WCX
Step4. 修改bootable/bootloader/uboot/Makefile,将MYOBJSDIR 中的obj 文件添加
到u-boot 的生成命令中,如下:
GEN_UBOOT = \
UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \
sed -n -e 's/.*$(SYM_PREFIX)__u_boot_cmd_.*/-u\1/p'|sort|uniq`;\
cd $(LNDIR) $(LD) $(LDFLAGS) $$UNDEF_SYM $(MYCUSTOMOBJS)
$(__OBJS) \
Case2. 该obj 文件在Codebase 中存在对应的.c 文件,现在需要将.c 文件删除,替
换为obj 文件
Step1. 编译生成obj 文件,uboot 编译生成的obj 文件与其.c 文件位于同级目录下
Step2.在原先obj 文件目录下创建一个文件夹prebuilt,并将obj 文件放入其中,同
时将.c 文件删除
Step3. 修改包含该.c 文件的Makefile 文件(一般与.c 文件位于同级目录下),将该obj
文件的名称从OBJS 变量中删除,同时在该Makefile 中添加一个变量,MYOBJS,将
该obj 文件添加到MYOBJS 中,以
bootable/bootloader/uboot/drivers/video/cfb_console.c 为例,修改该目录下的
Makefile 文件,将cfb_console.o 从变量OBJS 中删除,同时添加一行:
MYOBJS := cfb_console.o
Step4. 继续修改Step3 中的Makefile,将MYOBJS 添加到生成LIB 的命令中,如下:
$(LIB): $(OBJS) $(SOBJS)
$(AR) $(ARFLAGS) $@ $(OBJS) $(MYOBJS) $(SOBJS)
Case3. 某些模块,Uboot 和kernel 共用同一份Source code,比如LCM,这种情况
需要做特殊处理,以LCM 为例,如下:
Step1. 首先编译出obj 文件,路径位于:mediatek/custom/out/$project/uboot/lcm,
同时将要替换的Source code 删除(mediate/custom/common/kernel/lcm)
Step2. 在mediatek/custom/$project/uboot 下面添加lcm 文件夹,同时将Step1 中获
取到的obj 文件添加到该文件夹下,同时将原目录下的obj 文件删除(这里获取的
obj 文件一定要是Uboot 目录下的,不要到kernel 目录下获取这些obj 文件)
Step3. 修改mediatek/custom/common/uboot/Makefile 文件,将要替换的obj 文件
名称从COBJS 删除:COBJS += $(patsubst %.c, %.o, $(wildcard lcm/*.c))
Step4. 继续修改Step3 中的Makefile,添加如下Code:MYOBJS := $(addprefix $(obj),
$(wildcard lcm/*.o)),同时将MYOBJS 添加到$(LIB)的编译命令中,如下:
$(LIB): $(OBJS) $(SOBJS)
$(AR) $(ARFLAGS) $@ $(OBJS) $(MYOBJS) $(SOBJS)
说明:Uboot 的Source Code 主要位于如下路径:
– bootable/bootloader/uboot/
– mediatek/platform/$platform/uboot/
MEDIATEK CONFIDENTIAL
FOR zhanghui@ vanzotec.com USE ONLY
loginid=zhanghui@vanzotec.com,time=2013-10-08 19:27:59,ip=180.166.121.198,doctitle=如何在preloader、uboot、lk、kernel中预置obj文件.docx,company=Vanzo_WCX
– mediatek/custom/$platform/uboot/
– mediatek/custom/common/uboot/
– mediatek/custom/$porject/uboot/
3. 如何在kernel 中预置obj 文件?
Branch:GB, GB2, ICS
– 比如要将xxx.c 用xxx.o 替代编译
– 先正常编译出xxx.o
– 然后在xxx.c 所在目录下创建prebuilt 目录,将xxx.o 放入
? 注意prebuilt 目录的目录名不能修改,否则在clean 阶段会被清除
– 修改xxx.c 所在目录下的Makefile 文件,原本已经有obj-y := xxx.o,在其后
面添加xxx-y := prebuilt/xxx.o 即可
– mediatek/custom/[XXX]/kernel 目录下对应的Source Code 没有Makefile 文件,
自己在Source code 对应的同级目录下添加一个Makefile 即可
Branch:ICS2, JB, JB2
– 比如要将debug.c 用debug.o 替代编译
– 先正常编译出debug.o (针对kernel 和lk, uboot 共用Source Code 的情况,
如LCM,这里获取 到的obj 文件一定要是kernel/out 目录下的)
– 然后将debug.o 复制到原先debug.c 所在目录下,并重命名为
debug.o_shipped
– 原先debug.c 同级目录下的Makefile 不变,依然保持为
obj-y:=debug.o;mediatek/custom/[XXX]/kernel 目录下对应的Source Code 没有
Makefile 文件,自己在Source code 对应的同级目录下添加一个Makefile 即可
– 重新编译kernel 即可
说明:kernel 的Source code 主要位于如下路径:
– kernel/
– mediatek/platform/$platform/kernel/
– mediatek/[source]/kernel/
– mediatek/custom/$platform/kernel/
– mediatek/custom/common/kernel/
– mediatek/custom/$porject/kernel/
4. 如何在lk 中预置obj 文件
Branch:JB,JB2
Step1. 在bootable/bootloader/lk/makefile 中添加:MYOBJ :=
Step2. 获取obj 文件,Codebase 编译生成的obj 文件位于
bootable/bootloader/lk/build-$project/custom/$project/lk 目录下
Step3. 将获取的obj 文件放到与.c 文件相同目录下;同时可将.c 文件删除
MEDIATEK CONFIDENTIAL
FOR zhanghui@ vanzotec.com USE ONLY
loginid=zhanghui@vanzotec.com,time=2013-10-08 19:27:59,ip=180.166.121.198,doctitle=如何在preloader、uboot、lk、kernel中预置obj文件.docx,company=Vanzo_WCX
Step4. 将相应的.c 文件从包含该.c 文件的rules.mk(一般与.c 文件位于同级目录)中删
除
Step5. 将Step3 中添加的.o 文件在rules.mk 中添加到MYOBJ,比如MYOBJ += test.o
Step6. 打开bootable/bootloader/lk/make/build.mk,将MYOBJ 添加到OUTELF 的生
成命令中,如下:
else
$(OUTELF): $(ALLOBJS) $(LINKER_SCRIPT)
@echo linking $@
$(NOECHO)$(LD) $(LDFLAGS) -T $(LINKER_SCRIPT) $(ALLOBJS)
$(MYOBJ) $(LIBGCC) -o $@ endif
Step7. 如果要替换的.c 文件是lk 与kernel 共用的,比如lcm 模块,那么Step2 需要
做一下修改:将获取的obj 文件放到mediatek/custom/$project/lk/lcm 中,同时要
确保这里获取的obj 文件是bootable/bootloader/lk/build-
$project/custom/$project/lk 目录下的,不要到kernel/out 目录下获取这些obj 文件
说明:lk 的Source Code 主要位于如下路径:
– mediatek/platform/$platform/lk/
– mediatek/custom/$platform/lk/
– mediatek/custom/common/lk/
– mediatek/custom/$porject/lk/
– bootable/bootloader/lk/
MEDIATEK CONFIDENTIAL
linux试题求大神帮解一下赶时间谢谢了
1. 用grep命令显示在文件a中所有包含每个字符串至少有5个连续小写字符的字符串的行。
cat a | grep -E "[a-z]{5,}"
2. $ find / -name "test.c" -type f -mtime +3 -user greek -exec rm {} \;的含义。
找出并且删除根目录及其子目录下 所有文件名为test.c的普通的文本文件 ,且该文件的最后修改时间以当前时间为参照大于3天时间
3. 在一个程序崩溃时,它一般会在指定目录下生成一个core文件。如果没生成core文件,可能是什么原因?怎么解决?
答:用“ulimit -c”命令查看当前系统设置的core文件的大小门限值
一般情况是core文件的大小超过了这个值
执行 “ulimit -c unlimited”命令后,操作系统不在限制core文件大小,或者把unlimited 替换成一个适当的值。
4. 执行命令 ls –l 时,某行显示如下:
-rw-r--r-- 1 chris chris 207 jul 20 11:58 mydata
(1)用户chris对该文件具有什么权限?
答:chris对mydata文件具有读写的权限
(2)如何使任何用户都可以读写执行该文件?
答:chmod 777 mydata
5. 大学校门处要求来客登记,只有一张登记表,登记表同时只能由一个人使用,用P、V原语描述一个校外人员进入大学的过程。
三、程序填空题(每小题10分,共20分)1.阅读下面程序,请将其补充完整。
#define SHMDATASIZE 1000 //共享内存大小,以字节为单位
void server(void)
{
union semun sunion;
int semid, shmid;
void *shmdata;
char *buffer;
semid=semget(_________________);//创建两个信号量
sunion.val=1;
semctl(____________________);//设置信号量编号为0的值
sunion.val=0;semctl(____________________);//设置信号量编号为1的值
shmid=shmget(____________________);
shmdata=shmat(___________________);
*(int *)shmdata=semid;
buffer=shmdata+sizeof(int);
printf("Server is running with SHM id ** %d**\n", shmid);}
2.阅读下面程序,请将其补充完整。
#define BUFFERSIZE 1024
void locksem(int semid, int semnum)
{
struct sembuf sb;
sb.sem_num=semnum;
sb.sem_op=________;//P操作
sb.sem_flg=SEM_UNDO;
semop(_______________________);
}
void unlocksem(int semid, int semnum)
{
struct sembuf sb;
sb.sem_num=semnum;
sb.sem_op=________;//V操作
sb.sem_flg=SEM_UNDO;
semop(______________________);
}
void clientwrite(int semid, char *buffer){
locksem(semid, 0);
printf("Enter Message: ");
fgets(_______________);//从键盘输入一个字符串
unlocksem(semid, 1);
}
四、阅读程序题(共3小题,每小题10分,共30分)
1. 运行下面程序,最多运行多少个进程?画出进程家族树。
#include "stdio.h"
#include "sys/types.h"
#include "unistd.h"
int main()
{
pid_t pid1;
pid_t pid2;
pid1 = fork();
pid2 = fork();
}
答最多有4个进程
首先第一次调用fork 主进程会产生一个pid1的子进程
然后pid1和主进程会分别调用一次pid2 = fork(); 分别再产生一个子进程因此一共最多4个进程
2. 下面给出了一个SHELL程序,试对其行后有#(n)形式的语句进行解释,并说明程序完成的功能。
#!/bin/bash #(1)定义该shell脚本由哪中类型的shell解释器解析
dir=$1 #(2)将shell程序的第一个命令行参数付给变量dir
if [ -d $dir ] #(3)判断dir的值是否是一个目录
then cd $dir #(4)如果dir是目录则进入该目录
for file in *
do
if [-f $file ] #(5)判断file是否为一个文件
then
cat $file #(6)打开文件,将文件内容输出到标准输出流中
echo “end of file $file”
fi
done
else
echo “bad directory name $dir”
fi
3. 阅读Makefile文件,回答以下问题:
(1) 此Makefile文件的主要功能是什么?
编译f1.c f2.c f3.c三个文件,最终生成动态链接库libmys.so
(2) 此Makefile文件包含多少个规则?它们分别是什么?
包含4个规则
第一个 “TGT = $(patsubst %.c, %.o, $(SRC))”
将$(SRC)目录下的所有以.c为后缀的文件替换成.o结尾,且存入TGT变量中
第二个 “%.o : %.c
cc -c $”
用cc命令依次将三个源文件编译成目标文件
第三个
libmys.so : $(TGT)
cc -shared -o $@ $(TGT)
用上一步生成的3个中间文件生成动态链接库libmys.so
第四个
clean:
rm -f $(TGT)
执行 make clean 后 会删除所有的中间文件即.o文件
(3) 使用此Makefile文件可以生成目标文件f2.o吗?为什么?
答:可以,因为该makefile的逻辑是先生成所有的.o文件,然后再生成动态链接库。
all : libmys.so
SRC = f1.c f2.c f3.c
TGT = $(patsubst %.c, %.o, $(SRC))
%.o : %.c
cc -c $
libmys.so : $(TGT)
cc -shared -o $@ $(TGT)
clean:
rm -f $(TGT)
编程题没做,楼主一、见谅,有时间做了补充下答案