`
cloudtech
  • 浏览: 4606941 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

Barrelfish研究——分析hake

 
阅读更多

Barrelfish研究——分析hake

上一篇讲了Barrelfish的环境搭建。在搭建过程中,我们注意到一些步骤和通常编译Linux源码包的方法有不同之处。

类比

通常我们编译Linux源码包的步骤基本上都是先configure再make。这种包的源码管理是用的autotools。另外一种常见的源码管理工具是cmake。编译的方法是先cmake再make。以上的两种方法中,不论是configure还是cmake,它们的目的无非是进行一些平台相关的设置,源码结构的配置,然后生成相应的Makefile。有了Makefile之后,源码管理工具的任务到这里就完成了。后面的步骤基本一致。即执行make,批量(一般是用gcc)编译源码。

Barrelfish的编译过程不同在,其既不是执行configure也不是执行cmake,而是执行了hake.sh。执行过程中,也可以看到漫长的扫描过程,然后会在build目录下生成一个庞大的Makefile文件(大约十几MB)。后面同样也是执行make的过程。

在这个过程中,可以体会到hake.sh的角色,大概同autotools与cmake是相同的,即为生成Makefile。

分析hake.sh

执行hake.sh,打印所支持的选项如下:
-s|--source-dir: path to source tree (required)
-i|--install-dir: path to install directory (defaults to `pwd`)
-a|--architecture: specify archtitecture to build for (can be
    given multiple times, default architectures are
    "x86_64"
-n|--no-hake: just rebuild hake itself, don't run it (only useful
    for debugging hake)
阅读hake.sh,它主要做了以下几项工作:

第一

echo "Setting up hake build directory..."
if [ ! -f hake/Config.hs ]; then
    cp $SRCDIR/hake/Config.hs.template hake/Config.hs
    cat >> hake/Config.hs <<EOF


-- Automatically added by hake.sh. Do NOT copy these definitions to the defaults
source_dir = "$SRCDIR"
architectures = [ $ARCHS ]
install_dir = "$INSTALLDIR"
EOF
else
    echo "You already have Config.hs, leaving it as-is."
fi
通过Config的模板Config.hs.template创建一个新的Config.hs文件,并在文件末尾添加三个变量。这三个变量的值,当然是来于在自hake.sh的参数。

第二

if [ ! -f ./symbolic_targets.mk ]; then
    echo "Creating new symbolic_targets.mk file."
    cp "$SRCDIR/hake/symbolic_targets.mk" . 
else
    echo "You already have symbolic_targets.mk, leaving it as-is."
fi
创建一个新的symbolic_targets.mk文件

第三

ghc -O --make -XDeriveDataTypeable \
    -package ghc \
    -package ghc-paths \
    -o hake/hake \
    -outputdir hake \
    -i$SRCDIR/hake \
    -ihake \
    $SRCDIR/hake/Main.hs $LDFLAGS || exit 1
终于看到了ghc了。有人会问,为什么编译Barrelfish需要ghc,它在其中起什么作用?答案就在这里:ghc的作用就是编译一些hs为后缀名的Haskell源码,生成一个名为hake的程序。
第四
if [ "$RUN_HAKE" == "No" ] ; then
    echo "Not running hake as per your request."
    exit
fi
echo "Running hake..."
./hake/hake --output-filename Makefile --source-dir "$SRCDIR" || exit
注意hake.sh文件的第四个参数-n。如果你设置了这个参数,那么表示仅编译生成hake,并不执行hake。那么这个hake的程序做了哪些工作呢?

分析hake

上面说到,hake是用Haskell语言写的,其main函数所在文件名为Main.hs。如果你了解Haskell语言,那是再好不过的了。不过,如果不熟悉也没有关系,我们并不需要读懂它的每一行代码如何工作,只要知道它的大概功能就可以了。(Haskell语言是一个很值得学习的函数式编程语言,如果你未曾接触过函数式编程语言,花一点时间去了解一下Haskell是很有意义的!)

打开Main.hs文件,直奔末尾找到main函数

main :: IO() 
main = do
    -- parse arguments; architectures default to config file
    args <- System.Environment.getArgs
    let o1 = parse_arguments args
        al = if opt_architectures o1 == [] 
             then Config.architectures 
             else opt_architectures o1
        opts = o1 { opt_architectures = al }
    if opt_usage_error opts then do
	hPutStrLn stderr usage
        exitWith $ ExitFailure 1
      else do


    -- sanity-check configuration settings
    -- this is currently known at compile time, but might not always be!
    if isJust configErrors then do
	hPutStrLn stderr $ "Error in configuration: " ++ (fromJust configErrors)
	exitWith $ ExitFailure 2    
      else do


    hPutStrLn stdout ("Source directory: " ++ opt_sourcedir opts)
    hPutStrLn stdout ("BF Source directory: " ++ opt_bfsourcedir opts)
    hPutStrLn stdout ("Install directory: " ++ opt_installdir opts)
      
    hPutStrLn stdout "Reading directory tree..."
    l <- listFilesR (opt_sourcedir opts)
    hPutStrLn stdout "Reading Hakefiles..."
    hfl <- readHakeFiles $ hakeFiles l
    hPutStrLn stdout "Writing HakeFile module..."
    modf <- openFile ("Hakefiles.hs") WriteMode
    hPutStrLn modf $ hakeModule l hfl
    hClose modf
    hPutStrLn stdout "Evaluating Hakefiles..."
    inrules <- evalHakeFiles opts l hfl
    hPutStrLn stdout "Done!"
    -- filter out rules for unsupported architectures and resolve relative paths
    let rules = 
          ([(f, resolveRelativePaths opts (fromJust (filterRuleByArch rl)) (strip_hfn opts f))
           | (f,rl) <- inrules, isJust (filterRuleByArch rl) ])
    hPutStrLn stdout $ "Generating " ++ (opt_makefilename opts) ++ " - this may take some time (and RAM)..." 
    makef <- openFile(opt_makefilename opts) WriteMode
    hPutStrLn makef $ preamble opts args
    -- let hfl2 = [ strip_hfn opts (fst h) | h <- hfl ]
    hPutStrLn makef $ makeHakeDeps opts $ map fst hfl
    hPutStrLn makef $ makeMakefile rules
    hPutStrLn makef $ makeDirectories rules
    hClose makef
    exitWith ExitSuccess
大约50行左右的代码,看懂它,就是hake所做的工作啦。

如果你用的编辑器不错,可以看到以"--"开头的行被高亮显示(vim和gedit均可),这些行是的注释。"hPutStrLn stdout"开头的行表示在终端打印。忽略这些代码。前十行的功能主要是参数的处理,得到源码路径和安装路径。然后调用listFilesR函数,它的输入是一个目录的路径,然后递归扫描其中所有的文件,输出这些文件完整路径的列表。将这个列表传递给hakeFiles函数,过滤出以"/Hakefile"结尾的文件。(回想那个hello world例子程序中的Hakefile文件)然后将这些Hakefile输入到readHakeFiles函数,即可得到每个Hakefile文件的内容。再调用hakeModule函数,对这些内容做整理,输出到一个名为Hakefiles.hs的文件中。(如果觉得有点晕了,不妨停下来,看看build目录下是否有一个Hakefiles.hs文件。打开看看,会发现,这个庞大的Hakefiles.hs文件有点类似与每个子目录中Hakefile内容的一个大汇总。)现在看到evalHakeFiles,这个函数会调用runghc,以脚本方式运行Hakefiles.hs,生成的结果是一个HRule的列表。HRule类型的定义在HakeTypes.hs文件,用来表示hake自己定义的一些语法规则。再后面hPutStrLn makef开头的几行代码,就是往Makefile中写内容了。这些内容包括一下预先定义好的preamble、编译的依赖关系、以及那些HRule解析的结果。总而言之,这时,一个完整的Makefile就生成了。

大功告成,稍微整理一下思路,想一想hake到底是一个什么东西。它是用Haskell语言写的一个程序,这个程序分析Barrelfish源码的结构,从中找出每一个子目录中的Hakefile,这些Hakefile包含一些编译选项,由hake定义的一套语法规则写成。汇总它,解析它,生成一个巨大的Makefile。把后面编译Barrelfish的任务就交给make和gcc来完成,hake就可以功成身退了。

后记

hake的意思是鳕鱼。笔者后来找到了Barrelfish官方给出的技术文档TN-003-Hake.pdf,所叙述的工作流程与我们的分析几乎完全一致。只是在谈及hake的设计原则以及必要性方面,对文档中颇有些夸张的说法尚且不能完全赞同。不管怎样,通过对它的分析,了解了它在Barrelfish这个项目整体中所占的角色,方便了我们今后继续对这个系统的研究;并且还稍微学习了一下Haskell语言。收获还是很大的。
分享到:
评论

相关推荐

    docker-barrelfish:用于Barrelfish OS构建工具的Docker映像

    用于Barrelfish OS构建工具的...编译并运行为了首次编译操作系统,进入终端后需要执行以下命令: cd /barrelfish_build && /barrelfish_src/hake/hake.sh -s /barrelfish_src -a x86_64 cd /barrelfish_build && m

    bucketfish-docker:用于使用Docker编译Barrelfish以及与Gitlab CI Runners集成的设置

    带有Docker和Barrelfish的基于Gitlab的CI 该存储库设置CI测试环境以编译和测试Barrelfish代码存储库。 自举 在您的机器上安装docker。 遵循 TL; DR # remote the old docker sudo apt-get remove docker docker-...

    advanced_operating_systems_2020:ETHZ的高级操作系统课程

    :warning_selector: 如果您已注册此课程,则不要继续进行下去:提出自己的设计决策是项目和课程的组成部分。 看一下我们的实现可能会违反ETHZ准则。 先进的操作系统-FS20 本课程旨在使学生对现代多核操作系统的设计...

    Toxi / Oxy Pro 便携式气体检测仪参考手册 使用说明书

    Toxi Oxy Pro 便携式气体检测仪参考手册 使用说明书

    科傻模拟网优化操作-教程书

    官方的的说明书资料,部分视频说明在这里: https://www.bilibili.com/video/BV1Fz4y1d7rn/?spm_id_from=333.999.0.0&vd_source=13dc65dbb4ac9127d9af36e7b281220e

    node-v8.14.0-x64.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    2023商业银行数据资产体系白皮书,主要介绍了“三位一体”数据资产体系的构成与工作机制,以及商业银行数据资产体系建设实践

    2023商业银行数据资产体系白皮书 目录 第 1 章 数据资产化与数据要素市场化相辅相成,相互促进 第 2 章 数据资产化是企业数据治理向上演进的必经之路 第 3 章 数据资产体系发展概述 第 4 章 “三位一体”数据资产体系的构思 4.1“三位一体”数据资产体系的构成与工作机制 数据资产管理 数据资产运营 数据资产评价 数据资产体系工作机制 4.2“三位一体”数据资产体系的相互作用关系 4.3“三位一体”数据资产体系的构建 4.4“三位一体”数据资产体系的优势 第 5 章 商业银行数据资产体系建设实践 5.1商业银行开展数据资产体系建设的背景和目标 5.2商业银行数据资产体系建设的工作步骤 5.3上海银行数据资产体系建设实践的主要成果 第 6 章 数据要素流通市场赋能企业数据资产化 6.1全国多层次数据要素市场的建设 6.2上海数据交易所赋能企业数据资产化 6.3数据要素流通交易市场赋能企业数据资产化的展望 第 7 章 未来演进与展望

    基于微信小程序的助农扶贫小程序

    大学生毕业设计、大学生课程设计作业

    车辆销售数据Python爬取并做数据分析,项目源码注解清晰一看就懂.zip

    车辆销售数据Python爬取并做数据分析,项目源码注解清晰一看就懂

    毕业设计:基于SSM的mysql-学生社团管理系统(源码 + 数据库 + 说明文档)

    毕业设计:基于SSM的mysql_学生社团管理系统(源码 + 数据库 + 说明文档) 第2章 主要技术和工具介绍 1 2.1 JSP语言 1 2.2 MySQL数据库 1 2.3 jsp技术 2 2.4ssm简介 3 第3章 系统分析 1 3.1可行性分析 1 3.1.1经济可行性 1 3.1.2技术可行性 1 3.1.3操作可行性 1 3.2需求分析 1 3.3业务流程分析 2 3.4数据流程分析 3 第4章 系统设计 5 4.1系统结构设计 5 4.2功能模块设计 5 4.3数据库设计 6 4.3.1数据库设计概述 6 4.3.1概念设计 6 4.3.2表设计 7 第5章 系统实现 15 5.1基本任务 15 5.2登录模块的实现 15 5.2.1首页实现 15 5.2.2管理员后台登录 16 5.3用户模块的实现 19 5.3.1注册模块及登录的实现 19 5.2.2入团模块的实现 21 5.2.3场地预约模块的实现 22 5.4管理员模块的实现 24 5.4.1系统用户管理模块的实现 24 5.4.2活动公告管理模块的实现 26 5.5社团模块的实现 28 5.5.1活动信息

    大健康零售业务O2O数字化战略规划方案.pptx

    大健康零售业务O2O数字化战略规划方案.pptx

    数据中台项目主要岗位及其职责和任务

    数据中台项目主要岗位及其职责和任务

    node-v8.0.0-linux-armv7l.tar.gz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    流程制造行业数字化智能工厂总体规划建设方案.pptx

    流程制造行业数字化智能工厂总体规划建设方案.pptx

    c语言学生成绩管理系统源码.zip

    c语言学生成绩管理系统源码.zip

    DEV-C++-5.11下载链接

    DEV-C++-5.11下载链接

    电器租赁小程序.zip

    电器租赁小程序.zip

    学生成绩管理系统 数据结构与算法课程设计 C++.zip

    学生成绩管理系统 数据结构与算法课程设计 C++

    知乎小程序算法.zip

    知乎小程序算法.zip

    基于R语言SIR传染病传播的SIR模型,很全,可直接应用仿真模拟.rar

    基于R语言SIR传染病传播的SIR模型,很全,可直接应用仿真模拟.rar

Global site tag (gtag.js) - Google Analytics