3

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

我的项目由一个带有 Jamroot 的根目录和一个带有 Jamfile、C++ 文件、头文件和 Python 脚本的项目子目录组成。

在根目录中,我有一个看起来像这样的 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 ;

'convenient_copy' 确实很方便,但不幸的是,我没有找到太多关于它的文档。

无论如何,我的想法是,当我在“hello_world”项目目录中时,我会更改代码并定期输入“bjam”。这具有构建 Python 扩展然后运行 ​​test_hello_world_ext.py 文件的效果,该文件执行“导入 hello_world_ext”以测试扩展是否正确构建,然后是一堆相当琐碎的单元测试。如果它们都通过,则 bjam 报告成功。

问题似乎是有时 bjam 在运行“convenient_copy”规则之前运行 Python 测试,这意味着它在扩展的先前版本上执行测试,然后用新版本覆盖它。这意味着我经常不得不运行 bjam 两次。事实上,bjam 第二次知道某事已过时,因为它确实做了某事。第三次和随后的时间它什么都不做,直到我进行进一步的源更改。当依赖项不正确时,这就像经典的双重问题。

这样做的主要问题是它通常会导致成功构建失败(因为现有的扩展很糟糕),而其他时候它会显示错误的构建成功。实际上,我花了好几个星期才注意到这种行为,大约在同一时间我以为我要疯了,也许不是巧合……

它似乎在 Linux 上比在 OS X 上更频繁地执行此操作,但我并不完全确定。虽然感觉是这样,但我在两种环境之间分配的时间相当平等。

另外,我是唯一一个发现 bjam 的“jamfile”语法完全混乱的人吗?引擎盖下发生了很多我根本不理解的事情,或者可以找到足够的文档。我很乐意改用 make 或 SCons,但由于这里和那里的示例损坏,我无法让它们工作。真正让我感到困惑的是,bjam 在处理我的文件之前如何构建许多其他目标,我认为这会使编写 makefile 变得非常棘手?由于我对 GNU Make 和 SCons 非常熟悉,因此值得我花时间放弃 bjam 来使用其中之一吗?

4

1 回答 1

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 做任何事情,除了一些非常琐碎的事情,你绝对应该阅读它的用户手册。我个人的经验是,在从头到尾读完之后,我每天都会选择 Boost.Build 而不是其他构建系统。YMMV

于 2012-10-02T10:35:24.350 回答