Boost的bjam在构建完成之前运行测试

时间:2012-08-17 03:05:44

标签: boost boost-python bjam boost-build

我有一个相当简单的Boost.Python扩展,我用bjam构建。问题是,事情发生的顺序对我来说没有意义,我看不出如何解决它。

我的项目包含一个根目录,一个Jamroot,一个带有Jamfile,C ++文件,头文件和Python脚本的项目子目录。

在root中我有一个看起来像这样的Jamroot文件,很大程度上是从示例和文档中拼凑而成的。它与项目的Jamfile是分开的,因为我实际上想要在其他子目录中存在的几个项目中共享它。

import python ;

if ! [ python.configured ]
{
    ECHO "notice: no Python configured in user-config.jam" ;
    ECHO "notice: will use default configuration" ;
    using python ;
}

use-project boost
  : ./boost ;

project
  : requirements <library>/boost/python//boost_python ;

# A little "rule" (function) to clean up the syntax of declaring tests
# of these extension modules.
rule run-test ( test-name : sources + )
{
    import testing ;
    testing.make-test run-pyd : $(sources) : : $(test-name) ;
}

build-project hello_world ;
# build-project [[other projects]]... ;

然后我有一个子目录,其中包含我的'hello_world'项目(名称已更改以保护无辜者),其中包含一个Jamfile:

PROJECT_NAME = hello_world ;

import python ;

python-extension interpolation_ext :
  $(PROJECT_NAME).cpp
:
  <define>FOO
;

# Put the extension and Boost.Python DLL in the current directory, so that running script by hand works.
install convenient_copy
  : $(PROJECT_NAME)_ext
  : <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION
    <location>.
  ;

# Declare test targets
run-test $(PROJECT_NAME) : $(PROJECT_NAME)_ext test_$(PROJECT_NAME)_ext.py ;

那'easy_copy'肯定很方便,但不幸的是我没有找到很多关于它的文档。

无论如何,我的想法是,当我在“hello_world”项目目录中时,我会进行代码更改并定期输入“bjam”。这具有构建Python扩展然后运行test_hello_world_ext.py文件的效果,该文件执行'import hello_world_ext'来测试扩展已正确构建,然后进行一系列相当简单的单元测试。如果他们都通过了,那么bjam会报告成功。

问题似乎是有时bjam运行Python测试之前它运行'convenient_copy'规则,这意味着它会对之前的版本执行测试的扩展名,然后用新版本覆盖它。这意味着我经常不得不两次运行bjam。事实上,第二次bjam知道某些东西已经过时了,因为它确实有所作为。第三次及以后的时间它没有做任何事情,直到我做进一步的源更改。当依赖关系不正确时,这就像经典的双重制作问题。

这个问题的主要问题在于它通常无法成功构建(因为现有的扩展程序很糟糕),有时它会显示错误的构建成功。实际上我花了几个星期的时间才注意到这种行为,大约在同一时间我以为我疯了,也许并非巧合......

它似乎在Linux上比OS X更常用,但我不完全确定。虽然感觉如此,但我在两种环境之间的时间相当均等。

另外,我是唯一一个发现bjam的'jamfile'语法完全令人困惑的人吗?引擎盖下有很多我根本不理解的东西,或者可以找到足够的文档。我很乐意使用make或SCons,但由于这里和那里的例子不好,我无法得到那些工作。让我感到困惑的是bjam在进入我的文件之前如何构建许多其他目标,这会让我觉得编写一个makefile非常棘手?由于我对GNU Make和SCons非常熟悉,是否值得我放弃bjam而不是使用其中一个?

1 个答案:

答案 0 :(得分:2)

在jamfile中声明目标的顺序并不确定构建目标的顺序。使用依赖项来控制构建顺序。 它会在这里完成:

run-test规则更改为接受需求参数:

rule run-test ( test-name : sources + : requirements * )
{
    import testing ;
    testing.make-test run-pyd : $(sources) : $(requirements) : $(test-name) ;
}

修改$(PROJECT_NAME)目标声明以在convenient_copy上添加依赖项要求:

run-test $(PROJECT_NAME) : $(PROJECT_NAME)_ext test_$(PROJECT_NAME)_ext.py : <dependency>convenient_copy ;

关于jamfile语法的部分等:

如果你对Boost.Build做任何事情,除了非常琐碎的事情,你一定要阅读它的User Manual。我的个人经验是,从开始到结束阅读之后,我选择Boost.Build而不是其他构建系统。 YMMV