我正在尝试构建https://github.com/wallix/redemption,它使用bjam
,但我并不真正了解bjam
(而且我认为,鉴于我已经不真正了解make
和cmake
,我真的没有那么多空间留给另一种构建系统语言)。
更具体地说,我想在那里构建projects/qtclient,作为主项目的一部分;这样,当我运行tools/packager.py(从头开始重复bjam
构建过程)时,还可以在生成的.deb
中获得qtclient
可执行文件。
注意,当我是仓库的根目录时,对于主构建,我可以:
redemption.git$ bjam exe libs
warning: No toolsets are configured.
warning: Configuring default toolset "gcc".
warning: If the default is wrong, your build may not work correctly.
warning: Use the "toolset=xxxxx" option to override our guess.
warning: For more configuration options, please consult
warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html
...patience...
...found 2502 targets...
...updating 267 targets...
gcc.compile.c++ bin/gcc-9/debug/log.o
...
......而且它工作正常。如果我尝试从同一目录位置构建projects/qtclient
,它会失败:
redemption.git$ bjam projects/qtclient/
warning: No toolsets are configured.
warning: Configuring default toolset "gcc".
warning: If the default is wrong, your build may not work correctly.
warning: Use the "toolset=xxxxx" option to override our guess.
warning: For more configuration options, please consult
warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html
redemption-src: /home/USER
/home/USER/jam/redemption-config.jam: No such file or directory
/home/USER/jam/defines.jam: No such file or directory
Assume Qt5. (bjam -s qt5)
projects/qtclient/Jamroot:48: in modules.load
ERROR: rule "setvar" unknown in module "Jamfile</home/USER/src/redemption_git/projects/qtclient>".
/usr/share/boost-build/src/build/project.jam:372: in load-jamfile
/usr/share/boost-build/src/build/project.jam:64: in load
/usr/share/boost-build/src/build/project.jam:142: in project.find
/usr/share/boost-build/src/build/targets.jam:453: in find-really
/usr/share/boost-build/src/build/targets.jam:475: in class@project-target.find
/usr/share/boost-build/src/build-system.jam:724: in load
/usr/share/boost-build/src/kernel/modules.jam:295: in import
/usr/share/boost-build/src/kernel/bootstrap.jam:139: in boost-build
/usr/share/boost-build/boost-build.jam:8: in module scope
...但是如果我先将目录更改为projects/qtclient
,然后在那里调用bjam qtclient
(或只调用bjam
),它就会工作:
demption.git/projects/qtclient$ bjam qtclient
redemption-src: /home/USER/src/redemption_git
Assume Qt5. (bjam -s qt5)
warning: No toolsets are configured.
warning: Configuring default toolset "gcc".
warning: If the default is wrong, your build may not work correctly.
warning: Use the "toolset=xxxxx" option to override our guess.
warning: For more configuration options, please consult
warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html
warning: non-free usage requirements <threading>multi ignored
warning: in main-target QtCore at Jamroot:146
...patience...
...found 2454 targets...
...updating 107 targets...
qt5.moc bin/gcc-9/release/src/qt_input_output_api/moc_qt_input_output_clipboard.cpp
...
gcc.link bin/gcc-9/release/qt5client
...updated 107 targets...
对-这显示了错误'ERROR:模块“Jamfile〈/home/USER/src/redemption_git/projects/qtclient〉".”中的未知规则“setvar”是由于bjam
在“项目根”目录中运行,而不是在projects/qtclient
子目录中运行。
因此,现在我尝试将projects/qtclient
的构建集成到主Jamroot中;我试过在alias exe
行的末尾(分号之前)添加qtclient
:
alias exe : rdpproxy rdpclient rdpinichecker qtclient;
结果:构建甚至未启动:
redemption.git$ bjam libs exe
error: Unable to find file or target named
error: 'qtclient'
error: referred to from project at
error: '.'
我试着在alias exe
行的末尾添加projects/qtclient
:
alias exe : rdpproxy rdpclient rdpinichecker projects/qtclient;
结果:构建开始,但由于bjam
未在项目子目录中运行而失败(相同的错误:'错误:模块中的规则“setvar”未知'):
redemption_git$ bjam libs exe
warning: No toolsets are configured.
...
/home/USER/jam/redemption-config.jam: No such file or directory
/home/USER/jam/defines.jam: No such file or directory
Assume Qt5. (bjam -s qt5)
projects/qtclient/Jamroot:48: in modules.load
ERROR: rule "setvar" unknown in module "Jamfile</home/USER/src/redemption_git/projects/qtclient>".
/usr/share/boost-build/src/build/project.jam:372: in load-jamfile
/usr/share/boost-build/src/build/project.jam:64: in load
...
根据Boost-build - dependency on subproject target,我还尝试修改代码,使其具有以下内容,同时恢复原始alias exe
行:
import feature ;
feature.feature qtclient : : dependency free ;
project redemption
: requirements
$(REDEMPTION_CXXFLAGS)
$(REDEMPTION_FFMPEG_FLAGS)
$(REDEMPTION_BOOST_STACKTRACE_FLAGS)
$(GCOV)
<cxxflags>-fno-rtti
<toolset>gcc:<cxxflags>-pipe
# <cxx-lto-default>on
# <cxx-stack-protector-default>on # strong, all
# <cxxflags>-fpie
<qtclient>projects/qtclient//qtclient
: default-build release
;
...
alias exe : rdpproxy rdpclient rdpinichecker ;
...然后,构建再次启动,但由于bjam
未在项目子目录中运行而失败(相同的错误:'错误:模块中的规则“setvar”未知'):
$ bjam libs exe
warning: No toolsets are configured.
...
redemption-src: /home/USER
/home/USER/jam/redemption-config.jam: No such file or directory
/home/USER/jam/defines.jam: No such file or directory
Assume Qt5. (bjam -s qt5)
/home/USER/src/redemption_git/projects/qtclient/Jamroot:48: in modules.load
ERROR: rule "setvar" unknown in module "Jamfile</home/USER/src/redemption_git/projects/qtclient>".
/usr/share/boost-build/src/build/project.jam:372: in load-jamfile
...
此外,根据How to build multiple targets with Boost and Jamroot?,我尝试在alias exe
行的末尾添加对projects/qtclient/Jamroot
的引用:
alias exe : rdpproxy rdpclient rdpinichecker projects/qtclient/Jamroot;
这实际上运行并且构建完成,没有错误-但是在构建日志中的任何地方都没有提到“qtclient”,并且没有生成相应的可执行文件。
对于build-project
,我从bjam - how to always execute shell script before building a target?得到的结果也是如此:
build-project projects/qtclient//qtclient ;
...或用于
build-project projects/qtclient ;
我也试过作弊,只是从 shell 中调用:
Echo [ SHELL "cd projects/qtclient; bjam release qtclient" ] ;
...这确实构建了qtclient -但随后在开始构建主项目:(
之前擦除了build文件夹
那么,我如何让bjam
在子文件夹中编译一个额外的项目,作为主项目的一部分,正确地(这意味着bjam
会改变当前的工作目录到子文件夹,然后再试图构建额外的项目)?
1条答案
按热度按时间goqiplq21#
对,所以这是一个更复杂的事情,我来到了一个讨厌的变通方案-但是,总比没有好。这里有几个问题-首先,让我们看看子文件夹项目的Jamroot;我会把这个作为一个差异:
最初,它试图通过
[ SHELL "readlink -n -f ../.." ] ;
找到REDEMPTION_PUBLIC_PATH
-如果用readlink -f ../..
调用shell,它别无选择,只能引用它的CWD;它不“知道”它是否在项目的子文件夹中。幸运的是,原来有一个bjam
语法可以让jam文件找到自己的路径:path-constant
规则(boost-build/bjam constant for path to Jamroot),也就是上述更改所使用的规则,以提供对_INCLUDE_PATH
s和include
d文件的正确引用-这将消除“ERROR:模块”“中的规则“setvar””未知。完成后,* 下一个 * 问题是,如果从主Jamfile调用子文件夹项目的构建(例如,通过
build-project
),我们将得到一个新的错误:问题是主项目和子项目都做
include $(JAM_INCLUDE_PATH)/cxxflags.jam ;
等;我试着从子项目Jamroot中手动删除这些内容,因为构建是从主文件夹开始的-但最终我们遇到了子项目Jam,抱怨未知的内容:...所以它仍然需要那些文件,但是它们已经冲突了...所以这种方式行不通。
因此,我们必须再次回到“更改目录”,显然我们必须从shell执行此操作...因此,这部分位于主Jamroot中,再次显示为diff:
首先,我们想知道我们是在做调试还是发布构建;显然在bjam中这是一个“变体”,也是一种“特性”,我不知道如何读取它(Getting the build type/variant inside a bjam Jamfile / echo a feature?),所以我做了一个变通方案,使用命令行参数-当然,只有当你使用
bjam
命令,并在命令行中显式地包含debug
或release
时,这才是好的。然后,
notfile
被用来定义类似于新的、自定义/手动目标的功能--在某种意义上,我们可以调用post_qtclient
,它将触发libs
和exe
作为依赖项的构建;然后运行my-post-command
操作。此操作中的命令在shell中运行,因此我们可以将目录更改为子文件夹project,在debug或release(通过变量)中运行bjam
,完成后,将子文件夹project bin目录中的所有文件复制到主bin目录。这对于通过
bjam -a release post_qtclient
进行构建来说已经足够了--但是如果您打算运行debhelper
脚本来构建一个.deb包(通过这个库中的一个工具./tools/packager.py --build-package --force-build
来完成),这就不够了。为此,我们必须将生成的子文件夹的可执行文件复制到正确的 install 位置;这是通过
install-qtclient
“make”操作完成的(或者不管是什么)。在那里处理字符串是非常棘手的(留下注解以记录这一点)-所以最后,这一部分将硬编码的子文件夹项目可执行文件复制到“bin”安装位置,就像其他可执行文件一样-然而,使用X1 M22 N1 X,因为在这一块运行时,您访问的页面不存在!这通常会注意到安装部分;最后要确保子项目的可执行文件最终保存在.deb文件中,请按如下方式更改
/packaging/template/debian/rules
:...这最终会生成一个.deb文件,该文件中的子项目可执行文件与此过程的其他可执行文件位于同一个bin文件夹中。
请注意,由于缓存的原因,从头开始重建项目可能会很棘手,所以我在这里执行了以下命令来“清理所有内容”:
好吧,希望这就是问题所在...