Makefile笔记

objects := $(wildcard *.o)
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@

%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

.PHONY : clean
clean :
rm $(objects) # 或-rm或@rm
—————————————————————-
$@
表示规则中的目标文件集。

$%
仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是”foo.a(bar.o)”,那么,”$%”就是”bar.o”,”$@”就是”foo.a”。如果目标不是函数库文件(Unix下是[.a],Windows下是[.lib]),那么,其值为空。

$<
依赖目标中的第一个目标名字。如果依赖目标是以模式(即”%”)定义的,那么”$<“将是符合模式的一系列的文件集。注意,其是一个一个取出来的。

$?
所有比目标新的依赖目标的集合。以空格分隔。

当你希望只对更新过的依赖文件进行操作时,”$?”在显式规则中很有用,例如,假设有一个函数库文件叫”lib”,其由其它几个object文件更新。那么把object文件打包的比较有效率的Makefile规则是:

lib : foo.o bar.o lose.o win.o
ar r lib $?

$^
所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。

$+
这个变量很像”$^”,也是所有依赖目标的集合。只是它不去除重复的依赖目标。
—————————————————————-
sources = foo.c bar.c
sinclude $(sources:.c=.d)
# 变量$(sources)所有[.c]的字串都替换成[.d]
%.d: %.c
@set -e; rm -f $@; $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; sed ‘s,\($*\)\.o[ :]*,\1.o $@ : ,g’ < $@.$$$$ > $@; rm -f $@.$$$$
# main.o : main.c defs.h –> main.o main.d : main.c defs.h
—————————————————————-
make -n 或 –just-print
make -nw

The `-W’ flag provides two features:

* If you also use the `-n’ or `-q’ flag, you can see what `make’
would do if you were to modify some files.

* Without the `-n’ or `-q’ flag, when `make’ is actually executing
commands, the `-W’ flag can direct `make’ to act as if some files
had been modified, without actually modifying the files.

使用”-C”参数来指定make下层Makefile时,”-w”会被自动打开的

make -t 或 –touch
make -q 或 –question
make -s 或 –silent
make -C <dir> 或 –directory=<dir> 指定读取makefile的目录
make -i 或 –ignore-errors
make -k 或 –keep-going 及 .IGNORE目标
—————————————————————-
exec:
cd /home/hchen
pwd

exec:
cd /home/hchen; pwd
—————————————————————-
IMMEDIATE = DEFERRED
IMMEDIATE ?= DEFERRED
# 如果没定义
IMMEDIATE := IMMEDIATE
# 只能使用已定义好的变量
IMMEDIATE += DEFERRED or IMMEDIATE

For the append operator, `+=’, the right-hand side is considered
immediate if the variable was previously set as a simple variable
(`:=’), and deferred otherwise.

define IMMEDIATE
DEFERRED
endef
—————————————————————
ifeq (0,${MAKELEVEL})
cur-dir := $(shell pwd)
whoami := $(shell whoami)
host-type := $(shell arch)
MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
endif
—————————————————————
nullstring :=
space := $(nullstring) # end of the line
—————————————————————
libs_for_gcc = -lgnu
normal_libs =

ifeq ($(CC),gcc)
libs=$(libs_for_gcc)
else
libs=$(normal_libs)
endif

foo: $(objects)
$(CC) -o foo $(objects) $(libs)
—————————————————————
comma:= ,
empty:=
space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))
# 把$(foo)中的空格替换成逗号,所以$(bar)的值是”a,b,c”
—————————————————————
$(subst <from>,<to>,<text>)
$(patsubst <pattern>,<replacement>,<text>)
$(patsubst %.c,%.o,x.c.c bar.c)
$(strip <string>)
去掉<string>字串中开头和结尾的空字符
$(strip a b c )从”a b c “得到”a b c”
—————————————————————
$(dir <names…>)

名称:取目录函数–dir。
功能:从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(”/”)之前的部分。如果没有反斜杠,那么返回”./”。
返回:返回文件名序列<names>的目录部分。
示例: $(dir src/foo.c hacks)返回值是”src/ ./”。

$(notdir <names…>)

名称:取文件函数–notdir。
功能:从文件名序列<names>中取出非目录部分。非目录部分是指最后一个反斜杠(”/”)之后的部分。
返回:返回文件名序列<names>的非目录部分。
示例: $(notdir src/foo.c hacks)返回值是”foo.c hacks”。

$(suffix <names…>)

名称:取后缀函数–suffix。
功能:从文件名序列<names>中取出各个文件名的后缀。
返回:返回文件名序列<names>的后缀序列,如果文件没有后缀,则返回空字串。
示例:$(suffix src/foo.c src-1.0/bar.c hacks)返回值是”.c .c”。

$(basename <names…>)

名称:取前缀函数–basename。
功能:从文件名序列<names>中取出各个文件名的前缀部分。
返回:返回文件名序列<names>的前缀序列,如果文件没有前缀,则返回空字串。
示例:$(basename src/foo.c src-1.0/bar.c hacks)返回值是”src/foo src-1.0/bar hacks”。

$(addsuffix <suffix>,<names…>)

名称:加后缀函数–addsuffix。
功能:把后缀<suffix>加到<names>中的每个单词后面。
返回:返回加过后缀的文件名序列。
示例:$(addsuffix .c,foo bar)返回值是”foo.c bar.c”。

$(addprefix <prefix>,<names…>)

名称:加前缀函数–addprefix。
功能:把前缀<prefix>加到<names>中的每个单词后面。
返回:返回加过前缀的文件名序列。
示例:$(addprefix src/,foo bar)返回值是”src/foo src/bar”。

$(join <list1>,<list2>)

名称:连接函数–join。
功能:把<list2>中的单词对应地加到<list1>的单词后面。如果<list1>的单词个数要比<list2>的多,那么,<list1>中的多出来的单词将保持原样。如果<list2>的单词个数要比<list1>多,那么,<list2>多出来的单词将被复制到<list2>中。
返回:返回连接过后的字符串。
示例:$(join aaa bbb , 111 222 333)返回值是”aaa111 bbb222 333″。
—————————————————————
$(foreach <var>,<list>,<text>)
names := a b c d
files := $(foreach n,$(names),$(n).o)
# $(files)的值是”a.o b.o c.o d.o”。
—————————————————————
reverse = $(2) $(1)

foo = $(call reverse,a,b)
—————————————————————
sources = foo.c bar.c
ifneq ( $(MAKECMDGOALS),clean)
include $(sources:.c=.d)
endif
只要我们输入的命令不是”make clean”,那么makefile会自动包含”foo.d”和”bar.d”这两个makefile。
—————————————————————
There are two reasons to use a phony target: to avoid a
conflict with a file of the same name, and to improve performance.

.PHONY: all
all: prog1 prog2 prog3 prog4

—————————————————————

“-b”
“-m”
这两个参数的作用是忽略和其它版本make的兼容性。

“-B”
“–always-make”
认为所有的目标都需要更新(重编译)。

“-C <dir>;”
“–directory=<dir>;”
指定读取makefile的目录。如果有多个”-C”参数,make的解释是后面的路径以前面的作为相对路径,并以最后的目录作为被指定目录。如:”make -C ~hchen/test -C prog”等价于”make -C ~hchen/test/prog”。

“-debug[=<options>;]”
输出make的调试信息。它有几种不同的级别可供选择,如果没有参数,那就是输出最简单的调试信息。下面是<options>;的取值:
a — 也就是all,输出所有的调试信息。(会非常的多)
b — 也就是basic,只输出简单的调试信息。即输出不需要重编译的目标。
v — 也就是verbose,在b选项的级别之上。输出的信息包括哪个makefile被解析,不需要被重编译的依赖文件(或是依赖目标)等。
i — 也就是implicit,输出所以的隐含规则。
j — 也就是jobs,输出执行规则中命令的详细信息,如命令的PID、返回码等。
m — 也就是makefile,输出make读取makefile,更新makefile,执行makefile的信息。

“-d”
相当于”–debug=a”。

“-e”
“–environment-overrides”
指明环境变量的值覆盖makefile中定义的变量的值。

“-t”
“–touch”
相当于UNIX的touch命令,只是把目标的修改日期变成最新的,也就是阻止生成目标的命令运行

“-W <file>;”
“–what-if=<file>;”
“–new-file=<file>;”
“–assume-file=<file>;”
假定目标<file>;需要更新,如果和”-n”选项使用,那么这个参数会输出该目标更新时的运行动作。如果没有”-n”那么就像运行UNIX的”touch”命令一样,使得<file>;的修改时间为当前时间。
—————————————————————
http://www.chinaunix.net/jh/23/408225.html 及 make manual摘录

CVS-client笔记

cvs -d :pserver:usrname@127.0.0.1:/home/cvsroot/proj login
cvs import -m “msg” modulename
cvs ci -m “msg” modulename
cvs co -m “msg” modulename
cvs up modulename
cvs st modulename
cvs add modulename
cvs remove modulename
cvs update -D “2002-10-19 10:00:0 GMT”
cvs -q update -A
cvs tag tagname
cvs co -r tagname
cvs tag -b branchname

cd main_branch_working_directory
cvs update -j branchname
cvs ci -m “branchname and MAIN merged”

cvs -q export -r rev -d dir module

CVS-server笔记

rpm -q | grep cvs
groupadd cvs
useradd -g cvs -G cvs –d /home/cvsroot cvsroot
passwd cvsroot
chmod –R 770 /home/cvsroot
su – cvsroot
mkdir proj
cvs -d /home/cvsroot/proj init
chmod –R 770 /home/cvsroot/proj
exit
vim /etc/xinetd.d/cvspserver

service cvspserver
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = root
server= /usr/bin/cvs
server_args= -f –allow-root=/home/cvsroot/proj pserver
log_on_failure += USERID
}

vim /etc/services

cvspserver 2401/tcp #pserver cvs service
cvspserver 2401/udp #pserver cvs service

su – cvsroot
vim proj/CVSROOT/passwd
usrname::cvsroot

VNC笔记

rpm -q vnc vnc-server
sudo vi /etc/sysconfig/vncservers
vncpasswd
ls ~/.vnc
sudo /sbin/service vncserver start
vncviewer localhost:1

sudo vim /etc/sysconfig/iptables
-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 5901 -j ACCEPT
sudo /sbin/service iptables restart

c语言下的工厂模式——ipmi源码分析

背景简介
========
IPMI(Intelligent Platform Management Interface)是一套用于硬件平台管理的规范/接口。
官方网址:http://www.intel.com/design/servers/ipmi/index.htm
而IPMItool是用于管理和配置支持IPMI规范硬件的工具。
官方网址http://ipmitool.sourceforge.net/

IPMItool的架构
==============
源码目录如下
+—contrib //用于建立web管理页面的shell脚本
+—control //包含一些安装、配置信息
+—debian //包含changelog等信息
+—doc //man的帮助信息
+—include
| \—ipmitool //头文件定义
+—lib //对IPMI规范的对应实现,如ipmi_session.c处理session
\—src //此目录下是ipmitool的三个主程序
\—plugins // ipmi_intf.c interface一些通用功能的实现
+—bmc // ipmitool与bmc kernel driver之间的接口
+—imb // Intel IMB Interface
+—lan // IPMI v1.5 LAN Interface
+—lanplus // IPMI v2.0 RMCP+ LAN Interface
+—lipmi // Solaris x86 LIPMI interface
\—open // Linux OpenIPMI Interface [default]

C语言下的工厂模式
=================
从上述的目录结构不难看出,IPMItool设计上的一个重要特色就是将不同的interface看作plugin。从而使系统具有清晰的结构和良好的扩充性。

IPMI规范中定义的实体,如session,fru,sdr,chassis,sensor等等,都在lib中做对应的实现。这部分是与具体interface相分离的。interface的通用接口在include\ipmitool\ipmi_intf.h中定义;interface的通用功能实现,在\src\plugins\ipmi_intf.c中。值得注意的是,interface是IPMI规范中定义的概念,普通意义上的接口本文中均使用中文“接口”。

这种将通用接口与具体实现相分离的方式无疑就是一种简单工厂模式了。

实践
====
那么interface具体是怎么实现为plugin的呢?可以从一个具体的例子看一下。

include\ipmitool\ipmi_intf.h中用ipmi_intf定义了了
struct ipmi_intf {

struct ipmi_session * session;
struct ipmi_oem_handle * oem;
uint32_t my_addr;
uint32_t target_addr;

int (*setup)(struct ipmi_intf * intf);
int (*open)(struct ipmi_intf * intf);
void (*close)(struct ipmi_intf * intf);

};

与OO语言类似,struct内部定义了数据和方法。不同的是,方法采用的是函数指针的方式。因为没有this指针,所以函数的形参就是指向自身struct的指针。如setup。

而在具体实现中,如src\plugins\lan\lan.c中给出了具体的函数实现。如ipmi_lan_setup。在ipmi_lan_setup中,即可使用形参定义的intf指针实现对ipmi_intf结构中相应数据的操作。

struct ipmi_intf ipmi_lan_intf = {
name: “lan”,
desc: “IPMI v1.5 LAN Interface”,
setup: ipmi_lan_setup,
open: ipmi_lan_open,
close: ipmi_lan_close,
sendrecv: ipmi_lan_send_cmd,
sendrsp: ipmi_lan_send_rsp,
keepalive: ipmi_lan_keepalive,
target_addr: IPMI_BMC_SLAVE_ADDR,
};

gdb笔记

(gdb) set $i=0
(gdb) while argv[$i] != 0
>print argv[$i++]
>end

(gdb) x /2cb argv[0]
0xfef82b5e: 47 ‘/’ 114 ‘r’
(gdb) x /2tb argv[0]
0xfef82b5e: 00101111 01110010
(gdb) x /2tw argv[0]
0xfef82b5e: 01101111011011110111001000101111 01101111011101110010111101110100

>silent
>set $p=obj
>while $p != 0
>print $p->name
>set $p=$p->next
>end
>cont (断点不停)

backtrace (bt)
info frame
up
info frame
info locals
frame 0
return 10

call printf(“test\0”)
call fflush(0)

disassemble
watchpoint
display
info display show display

http://www.linuxforum.net/books/LinuxFAQ/program-gdb.html

vmware下将RH9内核升级至2.6

虚拟机版本vmware:4.5.1 build-7568
原内核版本Redhat 9 linux-2.4.20-8
待升级版本linux-2.6.11.7

下载内核linux-2.6.11.7.tar.bz2至/usr/src并解压
ln -s linux-2.6.11.7 linux-2.6
在/usr/src/linux/Documentation/Changes查看相应软件的版本要求

下载并安装module-init-tools-3.1.tar.bz2
# configure –prefix=/
# make moveold
# make all install
# ./generate-modprobe.conf /etc/modprobe.conf
下载并安装device-mapper-1.00.19-2.i386.rpm
下载并安装lvm2-2.00.25-1.01.i386.rpm,用rpm -ivph –nodeps –force
下载并安装mkinitrd-4.1.18-2.i386.rpm

在/usr/src/linux-2.6下make mrproper(如果之前未编译过,此步骤可省)
make menuconfig,选择编译的模块。
Device Drivers
Block devices
Default RAM disk size 改为8192
USB support
UHCI HCD 选中(或OHCI,EHCI单独无法工作)
其余模块根据实际情况选择
make all
make modules_install
make install
/etc/modprobe.conf中相应部分更改为
alias usbfs usbcore
alias usb-controller uhci-hcd
鼠标键盘部分(hid, mousedev, keybdev)等部分酌情修改
/etc/rc.sysinit中
usbdevfs改为usbfs
hid改为usbhid
mousedev和keybdev酌情修改(分别改为usbmouse和usbkeybd或注释掉)
/etc/grub.conf中
更改default
2.6内核部分加一句elevator=deadline
reboot

学习总结
openssl+openssh的设置,配合PuTTY的使用
/etc/inetd.conf增加ssh stream tcp nowait root /usr/sbin/tcpd sshd -i
密钥对的生成ssh-keygen(Linux/Win)
公钥拷贝至~/.ssh/authorized_keys,密钥在客户端使用
grep -rnH “pattern” *
find ./ -name ‘*name*’ -print
vim
set foldmethod=indent
zf%; zi; zo; zO; .,$ d
dmesg
cat /proc/version
insmod; lsmod; modprobe -l | grep usb
useradd -s /bin/bash -g lfs -m -k /dev/null lfs

cat > ~/.bash_profile << “EOF”
exec env -i HOME=$HOME TERM=$TERM PS1=’u:w$ ‘ /bin/bash
EOF

cat > ~/.bashrc << “EOF”
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
PATH=/tools/bin:/bin:/usr/bin
export LFS LC_ALL PATH
EOF

readelf -l filename | grep interpreter
ld –verbose | grep SEARCH

Sketch Me

诸位还能认得出我来么?这个时候就好想学画画。。。。 :-p

sketchme.jpg

 

海边

我也说不清为什么这样喜欢海边。陆地终结的时候,很多东西却刚开始舒展,比如视野,比如想象。。。

嘉盛网上课程笔记

一些图表
=======
蜡烛线
四大线型
蜡烛线汇总1
蜡烛线汇总2
蜡烛线汇总3
隔夜利息一览表

经济数据
=======
重大数据公布前,尽量先平仓位。规避风险
重大数据公布前,行情可能出现整理势

5个重要的经济数据

  1. 美国非农就业数据,每个月第一个星期的周五晚上21:30公布,经常造成相关货币对50点以上的跳动;
  2. 贸易收支(国际贸易帐),每个月第二个星期四公布;
  3. 国内生产总额(GDP),每年1,4,7,10月公布上一季度初值,之后还会公布修正值;相关货币常会有30点左右的跳动;
  4. 美联储的利率决定。当市场存在分歧时,对汇市有较大的影响;
  5. 日本的短观报告,日本对大中小型企业进行的市场报告。每个季度末或下一个季度初公布;

其他基本知识
==========

两个石油消耗大国:美国和日本
商品货币:加元,澳元,纽元(http://www.fimr.org/article/view.asp?id=465

美元相对欧元是高息货币
欧元相对日元是高息货币

星期三持仓过夜利息是平时的三倍

北京凌晨三点到7点:尾盘,大洋盘,波动较小
7点到下午3点:亚洲盘
下午3点到晚上:欧洲盘(入场)
晚8点到次日凌晨2、3点:美国盘(常会有大的数据公布)

看日线图和四小时图决定当天策略,方向(做一到两天)
看5分钟图决定具体的入场价位和出场价位
等一根蜡烛线走完再操作(每四小时完全结束时)

欧元对美元波动每日110到120左右
英镑对美元波动较大,每日140点左右

尽量选择止赢空间大于止损空间的交易,1:2左右,小于1:2少量操作或观望

真突破,往往可以停住4根k线;