patsubst如何读(spat怎么读音)

http://www.itjxue.com  2023-02-16 14:29  来源:未知  点击次数: 

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)

编程题没做,楼主一、见谅,有时间做了补充下答案

(责任编辑:IT教学网)

更多

推荐其它软件文章