【转】bitbake 笔记

原文 http://blog.chinaunix.net/uid-17188120-id-4081314.html

1 当你已经编完一个系统比如sato映像,在编一个meta-toolchain的映像如何重用已经下载的源码。
  修改build/local.conf变量
  DL_DIR=
2 如果你用ctl+c中断了编译过程,在重新编译的时候poky可能出现了一些问题。你个以这样做来避免出现问题。
  PC$rm -rf tmp/cache/default-glibc
  PC$rm -rf tmp/stamps/出现问题的包
3 增加编译的速度
  如果你是多核的计算机修改build/local.conf变量
  BB_NUMBER_THREADS = "4" 或 “2”
  PARALLEL_MAKE = "-j 4" 或 “-j 2”
4 TOPDIR=poky/build
5 git更新本地文件
  git checkout -f
  git clone git://git.pokylinux.org/poky.git
  cd poky/
  git remote add contrib git://git.pokylinux.org/poky-contrib.git
  git remote update
  git branch -r | grep ‘xf/distro‘
  git push [email protected]:poky-contrib.git contrbute-xiaofeng.yan:xiaofeng/distro
  git commit --amend --author=‘Xiaofeng Yan ‘
  ./create-pull-request -r origin/master -b xiaofeng/distro
   send-pull-request -t [email protected] -a -p pull-29801
  git checkout branch-->切换分支
 git

6 -sh: source: poky-init-build-env: file not found
  可能当前的用户环境有问题。这是可以换一个用户。但不是根用户。应该不是bash环境,详细请看/etc/passwd,看看是用那个shell
7 CLFLAGS_append = "-fPIC"
  如果要给gcc添加参数,可以用这个变量追加。
8 为什么文件的后面要加入这个变量BBCLASSEXTEND = "native"
  在解压源码包的时候出现了两个文件。而程序会进入只有patchs的目录下。
  这个不知道是什么原因?有待调查。
  这是因为在命名.bb文件的时候,一定按下列方式进行。例如:
  man-1.5.bb(错)
  man_1.5.bb(对)
  命名方式:名字_版本.bb 
9 如果在编译的过程中要使用root用户怎么办呢?
   在方法的前面加fakeroot
   例如:
   fakeroot do_configure(){
    
   }
10 fakeroot: FAKEROOTKEY set to 1844291688
  fakeroot: nested operation not yet supported
  上述的错误是因为如果在.bb 文件中使用了fakeroot的和环境,那么你就不能在单独的命令用fakeroot
  例如:
   fakeroot do_configure(){
    
   }
   do_compile(){
    fakeroot make -f Makefile //因为do_configure使用了fakeroot那么这里再用fakeroot就有问题了。正确的使用方法如下
   }  
   fakeroot do_dompile(){
    make -f Makefile
   }
11  .bb文件的语法
   do_configure (){
   }//正确的使用方法
   do_configure ()
   {
   }//错误的使用方法
12 如何在poky的环境下打补丁
   file://XXX.patch;patch=1  这种方法好像对传统的patch行不通。有待调查。
   可以用这种方式用以前的方式打patch
   do_configure_prepend() {
                patch -p0 < ${WORKDIR}/man-1.5k-confpath.patch
                patch -p1 < ${WORKDIR}/man-1.5h1-make.patch
}
13 do_configure 方法可能和bitbake默认的不一样,具体差异有待调查。
14 如何打印环境变量
   环境变量只有在compile和install阶段在能够通过echo命令在屏幕上输出。
   如果想在其他阶段看环境变量的值可以用下面的方法:例如
   do_configure (){
           ${S}/configure
           echo ${S} > 1.log
           echo ${D} >> 1.log
}
PC$bitbake PACKAGENAME -c devshell
devshell$vim 1.log
/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4
/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/image
15 如何开各个过程具体过程以及bb文件隐含的变量值和默认的 build过程。
   看build/tmp/work/arch/package/temp/run.do_*的其中一个文件有详细的说明。
16 貌似函数与函数之间要有一行空行。
17 通常修改的是packages/tasks里的一个描述任务的bb文件。
你可以通过
bitbake -g 映像名称
生成映像的依赖关系。然后在生成的depends.dot中找到映像依赖packages/tasks目录的哪些bb文件。然后在这些bb文件中找一个合适的位置加入your_bb。

假设映像依赖task-base.bb,你只要在task-base.bb中的
RDEPENDS_task-base = "\
下增加一行your_bb就可以了。
当然最好找一个与要增加的package比较相近的bb文件和任务。例如在poky中我在task-poky.bb
RDEPENDS_task-poky-apps-x11-core = "\
中增加我的package。

假设你修改了task-base.bb,只要重新bitbake 这个bb文件再bitbake 映像就可以了。
18 如何在bb文件中使用bash编程
   例如:
pkg_postinst_dpkg () {
#!/bin/sh
if [ "x$D" != "x" ]; then
        install -d $D/${sysconfdir}/rcS.d
        # this happens at S98 where our good ‘ole packages script used to run
        echo -e "#!/bin/sh
        dpkg --configure -a
        rm -f /${sysconfdir}/rcS.d/S${DPKG_INIT_POSITION}configure
" > ${IMAGE_ROOTFS}/${sysconfdir}/rcS.d/S${DPKG_INIT_POSITION}configure
        chmod 0755 $D/${sysconfdir}/rcS.d/S${DPKG_INIT_POSITION}configure
fi
}
19  变量赋值和引号:
   
    所有的变量赋值时,内容要用双引号括起来。(如果不用可能现在能工作,但后面就不一定能工作
    了)
   
        VAR1 = "${OTHERVAR}"
        VAR2 = "The version is ${PV}"
20  变量值追加(有空格):+=
   
    你可以给已经有值的变量使用符号“+=”追加一个值。注意这个操作会在原值和你追加的值中间添
    上空格:
   
        SRC_URI += "file://fix-makefile.patch;patch=1"       
       
变量值前加:=+
   
    你可以给已有值的变量内容前面加上一个值,使用符号"=+".注意这个操作会在原值和你追加的值中间添
    上空格:
       
        VAR =+ "Starts"
   
   
变量值追加:_append方式

你可以使用_append方式来给一个已经存在的变量追加值,跟+=不一样的是这种方式不会在原值和
    你要追加的值中间加上空格。下面的例子中自己添上了空格,这样就不会跟原来的值直接合在一起。
   
        SRC_URI_append = " file://fix-makefile.patch;patch=1"
       
    _append方式也可以用来覆盖某个值,但是仅仅是在指定目标机器和平台的时候有用:
       
        SRC_URI_append_sh4 = " file://fix-makefile.patch;patch=1"
       
    你可以把追加符理解为变量自己本身。所以+=和=+符号可以和_append一起来使用,比如:
   
    SRC_URI_append = " file://fix-makefile.patch;patch=1"
    SRC_URI_append += "file://fix-install.patch;patch=1"

变量值前加:_prepend 方式

使用_prepend在已有的变量前面加上一个值。和_apend一样,这里_prepend和=+的区别就是没有
    空格。
   
    例如:CFLAGS_prepend = "-I${S}/myincludes "
   
    同样在指定机器名的时候_prepend也是覆盖的意思。如:
   
        CFLAGS_prepend_sh4 = " file://fix-makefile.patch;patch=1"
   
    同样_prepend也可以和+=,=+一起来使用,例如:
   
        CFLAGS_prepend = "-I${S}/myincludes "
        CFLAGS_prepend += "-I${S}/myincludes2 "
   
空格和制表符

缩进应该使用空格,而不是制表符。所以说现在制表符也可以工作,但是OE只是承诺过支持空格。
   
代码风格:oe-stylize.py

为了帮助你在“配方“中使用正确的(译者注:标准的可能更合适些)格式,oe在contrib目录里
    提供了一个oe-stylize.py脚本,使用它你可以把你的“配方”格式化成标准的格式.运行脚本的
    时候会输出一些警告信息,你需要手动把这些删除.
   
        contrib/oe-stylize.py myrecipe.bb > fixed-recipe.bb
        vi fixed-recipe.bb
        mv fixed.recipe.bb myrecipe.bb
       
使用python的高级操作:${@...}

为了获取更高级的功能,你可以使用python语句,比如变量替换和搜索。
   
    Python语句在声明变量之前要添加@符号。
   
        CXXFLAGS := "${@‘${CXXFLAGS}‘.replace(‘-frename-registers‘, ‘‘)}"

21 sysroot目录是存放中间过程的头文件和库等。用于其他包编译所需的依赖。
22 The BBCLASSEXTEND = "native" says this package can be built both as a native host package, as well as a target package.

| rm: cannot remove `/usr/share/man/man1/ldd.1.gz‘: Permission denied
| rm: cannot remove `/usr/share/man/man1/time.1.gz‘: Permission denied
| rm: cannot remove `/usr/share/man/man2/_Exit.2.gz‘: Permission denied
| rm: cannot remove `/usr/share/man/man2/__clone2.2.gz‘: Permission denied
| rm: cannot remove `/usr/share/man/man2/_exit.2.gz‘: Permission denied
   ...... 
解决办法是增加了MANDIR
do_compile() {
        oe_runmake -f Makefile DESTDIR=${D} MANDIR=${D}${mandir}
}
24 有这样的问题:
do_configure (){
        ${S}/configure 
}

do_compile (){
        oe_runmake -f Makefile mandir=${D}${mandir}
}

fakeroot do_install(){
        mkdir -p ${D}/usr/local/man/man1
        mkdir -p ${D}/usr/local/man/man5
        mkdir -p ${D}/usr/local/man/man7
        oe_runmake install DESTDIR=${D}
}

NOTE: make install DESTDIR=/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/image
make[1]:
Entering directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4‘
make[2]:
Entering directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/src/include‘
test
-d /usr/local/man ||
/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/mkinstalldirs
/usr/local/man
test
-d /usr/local/man/man1 ||
/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/mkinstalldirs
/usr/local/man/man1
mkdir /usr/local/man/man1
mkdir: cannot create directory `/usr/local/man/man1‘: Permission denied
make[2]: [install_man] Error 1 (ignored)
test
-d /usr/local/man/man5 ||
/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/mkinstalldirs
/usr/local/man/man5
mkdir /usr/local/man/man5
mkdir: cannot create directory `/usr/local/man/man5‘: Permission denied
make[2]: [install_man] Error 1 (ignored)
test
-d /usr/local/man/man7 ||
/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/mkinstalldirs
/usr/local/man/man7
mkdir /usr/local/man/man7
mkdir: cannot create directory `/usr/local/man/man7‘: Permission denied
make[2]: [install_man] Error 1 (ignored)
make[2]:
Leaving directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/src/include‘
make[2]:
Entering directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/src/libs/libgroff‘
make[2]:
Leaving directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/src/libs/libgroff‘
make[2]:
Entering directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/src/libs/libdriver‘
make[2]:
Leaving directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/src/libs/libdriver‘
make[2]:
Entering directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/src/libs/libbib‘
make[2]:
Leaving directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/src/libs/libbib‘
make[2]:
Entering directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/src/roff/groff‘
test
-d /usr/local/bin ||
/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/mkinstalldirs
/usr/local/bin
rm -f /usr/local/bin/groff
/usr/bin/install -c groff /usr/local/bin/groff
/usr/bin/install: cannot create regular file `/usr/local/bin/groff‘: Permission denied
make[2]: *** [install_prog] Error 1
make[2]:
Leaving directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4/src/roff/groff‘
make[1]: *** [src/roff/groff] Error 2
make[1]:
Leaving directory
`/home/yxfyanxiaofengyxf/mydata/poky/green-3.3/build/tmp/work/i586-poky-linux/groff-1.18.1.4-r0/groff-1.18.1.4‘
make: *** [install] Error 2
FATAL: oe_runmake failed
ERROR: Function do_install failed
这个问题是这样解决的
do_configure (){
        mkdir -p ${D}/usr/local
        ${S}/configure --prefix=${D}/usr/local
}

do_compile (){
        oe_runmake -f Makefile mandir=${D}${mandir}
}

fakeroot do_install(){
        mkdir -p ${D}/usr/local/man/man1
        mkdir -p ${D}/usr/local/man/man5
        mkdir -p ${D}/usr/local/man/man7
        oe_runmake install DESTDIR=${D}
}
25 ipk的包的形成是怎么形成的,貌似自动install的好多文件没有打进ipk包中。不知道这个问题怎么解决。
   目前暂时解决的办法,${PN}-locale的包默认貌似没有打进image中。如果想要把想要的东西打进image中可以 这样做:
   FILES_${PN} += "${datadir}/locale"

26 下列是一些重要變量的值。
   ${datadir}=/usr/share
   ${sysconfdir}=/etc
   sharedstatedir = /com
   ${STAGING_DIR_HOST} = sysroot
   --host=${BUILD_SYS}
   TARGET_ARCH
27 如何定义自己的目录变量
   PC$vim conf/bitbake.conf
   在合适的位置上添加自己的变量。
28 _prepend和_append注意家空格。
29 do_postinst_${PN}(){
    装载后进行的动作,包的内容可用
   }
   do_preinst_${PN}(){
     装载前进行的动作,包的内容不可用。
   }
   do_prerm_${PN}(){
     卸载前进行的动作,包的内容可用
   }
   do_postrm_${PN}(){
     卸载后进行的动作,包的内容不可用。
   }
30 对于patch问题,貌似只有在
    PC$bitbake packagename -c devshell
   PC$quilt new xxx.patch
   PC$quilt add file
   PC$quilt refresh
  这样形成的patch,才能够先这样运用
  file://xxx.patch;patch=1
  其他只能用do_configure_prepend(){}中实现。
31 doc locale 形成的ipk包貌似不会默认打入image.这个开关在哪里还需调查。
32 如何用gcc的参数定义一个宏的字符串
   gcc -DVAR=‘"hello"‘
   注意单双引号的用法,先单好在双号。 
33  EXTRA_OEMAKE = "CC=‘${CC}‘"有时候在编译的过程中会出现错误。可以用这个选项。
34 a patch line would be changed from:

file://some.patch;patch=1;pnum=2

to:

file://some.patch;striplevel=2

and a patch line:

file://another.diff;patch=1;pnum=1

could be changed to:

file://another.diff 
35 ${HOST_ARCH}表示当前的体系结构 ${BUILD_ARCH}
36 LIC_FILES_CHKSUM = "file://README;beginline=5;endline=29;md5=af80f631f3848bd0e9478df399015287"
   如何得到校验和。
   将一个错误的校验和放在md5=xxx
   在运行bitbake man-pages 的时候回报错,并返回一个正确的校验值。
37 update-alternatives --install ${bindir}/last last last.${PN} 200
   这句话的意思是:先install last,然后mv last last.${PN},然后ln -s last.${PN} last. 200是优先级貌似越大优先级越高。
38 PARALLEL_MAKE = ""
   当你看到并行编译的时候出现了问题,但是log里却没有错误,可是又编译不过去,那么就用上面的变量加入PARALLEL_MAKE = "-j 1"不让并行编译。
39 如果在编译的过程中,出现了这样的提示;
   No rule to make target "aaa", needed by `bbb`. Stop
   一般出的问题是由于你的bbb 需要用到你的aaa, 而makefile中你的aaa的路径是错误的。 把aaa的路径修改为正确的路径就OK了。
   还有一种可能就是在编译bbb的时候需要 aaa,但是却没有aaa这个库文件。解决的办法就是,就是先编译这个库文件。
   do_compile_prepend(){
        if [ -d tools ];then
                make -C tools/gnulib/lib
        fi
   }
40 如果在链表中增加了包,比如在poky-iamge-lsb的情况下。
   你需要增加这些步骤
   PC#bitbake task-poky-lsb -c clean
   PC#bitbake poky-image-lsb -c clean
   PC#rm sstate-contorl/sstate-package-name
   PC#bitbake poky-image-lsb
41 放送patch
   1. install the msmtp
      PC#sudo apt-get install msmtp
   2. create the msmtp config file like
      PC#vim /home/yan/.msmtprc:
      tls on
      tls_certcheck off
      tls_starttls on
      port 25

host prod-webmail.windriver.com
      from  [email protected]
      auth on
      user xyan
      password !yan1223
  3. You can double check if /usr/sbin/sendmail links to msmtp, If not, just link it
      PC# sudo ln -sf `which msmtp` /usr/sbin/sendmail 
42 bitbake eglibc -e
   看打包时,eglibc里的变量的值,比如PACKAGE
43   
bitbake -b qt-x11-free-native_3.3.5.bb -e | grep ^PROVIDES
bitbake -b qt-x11-free-native_3.3.5.bb -e | grep ^PN
44 提供者的错误解决。
NOTE: Resolving any missing task queue dependencies
ERROR:
Nothing RPROVIDES ‘gtk+-demo‘ (but
/buildarea/yxf/poky.gtk_direectfb/meta/recipes-graphics/tasks/task-gtk-directfb.bb
RDEPENDS on or otherwise requires it)
NOTE: Runtime target ‘gtk+-demo‘ is unbuildable, removing...
Missing or unbuildable dependency chain was: [‘gtk+-demo‘]
ERROR: Required build target ‘core-image-gtk-directfb‘ has no buildable providers.

这个就是说,没有找到gtk+-demo这个包的提供者。

$vi meta/recipes-gnome/gtk+/gtk+.inc

加入下面的语句

PACKAGES += "libgail gtk+-demo"

FILES_gtk+-demo = "         ${datadir}/gtk-2.0/demo/*         ${bindir}/gtk-demo         "

其实,bitbake提供者就是看PACKAGES里定义的包的名字。

时间: 2024-10-10 05:52:43

【转】bitbake 笔记的相关文章

【安全牛学习笔记】

弱点扫描 ╋━━━━━━━━━━━━━━━━━━━━╋ ┃发现弱点                                ┃ ┃发现漏洞                                ┃ ┃  基于端口五福扫描结果版本信息(速度慢)┃ ┃  搜索已公开的漏洞数据库(数量大)      ┃ ┃  使用弱点扫描器实现漏洞管理            ┃ ╋━━━━━━━━━━━━━━━━━━━━╋ [email protected]:~# searchsploit Usage:

51CTO持续更新《通哥的运维笔记》

<通哥的运维笔记>将持续在51CTO网站更新,希望大家多多关注.互相学习,后期,我将会退出<通哥的运维笔记>系列视频教程,希望带给大家最大的收获,帮助大家更好的学习.进步.<通哥的运维笔记>主要从linux系统管理.虚拟化.cloudstack云平台以及网络管理之CCNA.CCNP.CCIE,等等方面深入讲解.

WPF笔记整理 - Bitmap和BitmapImage

项目中有图片处理的逻辑,因此要用到Bitmap.而WPF加载的一般都是BitmapImage.这里就需要将BitmapImage转成Bitmap 1. 图片的路径要用这样的,假设图片在project下的Images目录,文件名XXImage.png. pack://application:,,,/xxx;component/Images/XXImage.png 2. 代码: Bitmap bmp = null; var image = new BitmapImage(new Uri(this.X

java String 类 基础笔记

字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String s = "abc";//存放于字符串常量池,产生1个对象 String s1=new String("abc");//堆内存中new创建了一个String对象,产生2个对象 String类中的equals比较字符串中的内容. 常用方法: 一:获取 1.获取字符串中字符的个数(长度):length();方法. 2.根据位置获取字符:charAt(int index); 3.根据字符获取在字符串中

vector 学习笔记

vector 使用练习: /**************************************** * File Name: vector.cpp * Author: sky0917 * Created Time: 2014年04月27日 11:07:33 ****************************************/ #include <iostream> #include <vector> using namespace std; int main

学习笔记之邮件发送篇

用脚本语言发送邮件是系统管理员必备技能 对系统定期检查或者当服务器受到攻击时生成文档和报表. 发布这些文档最快速有效的方法就是发送邮件. python中email模块使得处理邮件变得比较简单 发送邮件主要用到了smtplib和email两个模块,这里首先就两个模块进行一下简单的介绍: 本段摘录于    http://www.cnblogs.com/xiaowuyi/archive/2012/03/17/2404015.html 1.smtplib模块 smtplib.SMTP([host[, p

15.1-全栈Java笔记:Java事件模型是什么?事件控制的过程有哪几步??

应用前边两节上一章节的内容,大家可以完成一个简单的界面,但是没有任何的功能,界面完全是静态的,如果要实现具体功能的话,必须要学习事件模型. 事件模型简介及常见事件模型 对于采用了图形用户界面的程序来说,事件控制是非常重要的. 一个源(事件源)产生一个事件并把它(事件对象)送到一个或多个监听器那里,监听器只是简单地等待,直到它收到一个事件,一旦事件被接收,监听器将处理这些事件. 一个事件源必须注册监听器以便监听器可以接收关于一个特定事件的通知. 每种类型的事件都有其自己的注册方法,一般形式为: v

Java设计模式学习笔记,一:单例模式

开始学习Java的设计模式,因为做了很多年C语言,所以语言基础的学习很快,但是面向过程向面向对象的编程思想的转变还是需要耗费很多的代码量的.所有希望通过设计模式的学习,能更深入的学习. 把学习过程中的笔记,记录下来,只记干货. 第一部分:单例模式的内容 单例模式:类只能有一个实例. 类的特点:1.私有构造器:2.内部构造实例对象:3.对外提供获取唯一实例的public方法. 常见的单例模式实现有五种形式: 1.饿汉式. 2.懒汉式. 3.双重检查锁式. 4.静态内部类式. 5.枚举式. 以下分别

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeplex.com/ 文档也写的很详细,自己在看它的文档和代码时写了一些demo和笔记,还有它实现的原理记录一下 学习Caliburn.Micro要有MEF和MVVM的基础 先说一下他的命名规则和引导类 以后我会把Caliburn.Micro的 Actions IResult,IHandle ICondu