gcc bjam -构建子文件夹项目(在构建之前将目录更改为子文件夹项目)

tyg4sfes  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(178)

我正在尝试构建https://github.com/wallix/redemption,它使用bjam,但我并不真正了解bjam(而且我认为,鉴于我已经不真正了解makecmake,我真的没有那么多空间留给另一种构建系统语言)。
更具体地说,我想在那里构建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会改变当前的工作目录到子文件夹,然后再试图构建额外的项目)?

goqiplq2

goqiplq21#

对,所以这是一个更复杂的事情,我来到了一个讨厌的变通方案-但是,总比没有好。这里有几个问题-首先,让我们看看子文件夹项目的Jamroot;我会把这个作为一个差异:

diff --git a/projects/qtclient/Jamroot b/projects/qtclient/Jamroot
index 2379580db..d72e3edb5 100644
--- a/projects/qtclient/Jamroot
+++ b/projects/qtclient/Jamroot
@@ -1,6 +1,13 @@
-REDEMPTION_PUBLIC_PATH ?= [ SHELL "readlink -n -f ../.." ] ;
+#REDEMPTION_PUBLIC_PATH ?= [ SHELL "readlink -n -f ../.." ] ;
 
-ECHO "redemption-src: $(REDEMPTION_PUBLIC_PATH)" ;
+path-constant MYPATH : . ;
+REDEMPTION_PUBLIC_PATH ?= [ SHELL "readlink -n -f $(MYPATH)/../.." ] ;
+
+ECHO "qtclient Jamroot: MYPATH $(MYPATH)" ;
+ECHO "qtclient Jamroot: REDEMPTION_ROOT_PATH $(REDEMPTION_ROOT_PATH:E=not_set)" ;
+ECHO "qtclient Jamroot: REDEMPTION_PUBLIC_PATH $(REDEMPTION_PUBLIC_PATH)" ;
+ECHO "qtclient Jamroot: .all-features $(.all-features:E=not_set)" ;
+#ECHO [ SHELL "pstree -s -p $$ && echo PID $$ PWD $PWD" ] ;
 
 JAM_INCLUDE_PATH ?= $(REDEMPTION_PUBLIC_PATH)/jam ;
 REDEMPTION_INCLUDE_PATH ?= $(REDEMPTION_PUBLIC_PATH)/include ;
@@ -124,7 +131,7 @@ add_obj graphics.o : src/qt_input_output_api/graphics.cpp ;
 
 local requirement_list = ;
 # generated by `bjam targets.jam` from redemption project
-include redemption_deps.jam ;
+include $(MYPATH)/redemption_deps.jam ;
 
 
 constant EXE_DEPENDENCIES :

最初,它试图通过[ 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),我们将得到一个新的错误:

/usr/share/boost-build/src/build/feature.jam:140: in feature from module feature
error: feature already defined:
error: in feature declaration:
error: feature "<cxx-color>" : "_" "default" "auto" "never" "always" : "propagated"

问题是主项目和子项目都做include $(JAM_INCLUDE_PATH)/cxxflags.jam ;等;我试着从子项目Jamroot中手动删除这些内容,因为构建是从主文件夹开始的-但最终我们遇到了子项目Jam,抱怨未知的内容:

/usr/share/boost-build/src/kernel/modules.jam:107: in modules.call-in
ERROR: rule "Jamfile</home/USER/src/redemption.git/projects/qtclient>.flags" unknown in module "Jamfile</home/USER/src/redemption.git/projects/qtclient>".

...所以它仍然需要那些文件,但是它们已经冲突了...所以这种方式行不通。
因此,我们必须再次回到“更改目录”,显然我们必须从shell执行此操作...因此,这部分位于主Jamroot中,再次显示为diff:

diff --git a/Jamroot b/Jamroot
index eb4188fdd..e4a756002 100644
--- a/Jamroot
+++ b/Jamroot
@@ -46,6 +46,27 @@ JAM_INCLUDE_PATH ?= jam ;
 #
 #############################
 
+path-constant REDEMPTION_ROOT_PATH : . ;
+ECHO "main: REDEMPTION_ROOT_PATH $(REDEMPTION_ROOT_PATH)" ;
+import modules ;
+tbuildcmd = "" ;
+local args = [ modules.peek : ARGV ] ;
+if clean in $(args)
+{
+  tbuildcmd = clean ;
+}
+else if release in $(args)
+{
+  tbuildcmd = release ;
+}
+else if debug in $(args)
+{
+  tbuildcmd = debug ;
+}
+echo "tbuildcmd $(tbuildcmd)" ;
+echo "ARGV: $(args)" ;
+echo "INSTALLDIR/BINPREFIX: $(INSTALLDIR:E=not_set)$(BIN_PREFIX:E=not_set)" ;
+
 include $(JAM_INCLUDE_PATH)/redemption-config.jam ;
 include $(JAM_INCLUDE_PATH)/cxxflags.jam ;
 include $(JAM_INCLUDE_PATH)/defines.jam ;
@@ -154,10 +175,22 @@ alias install :
     install-etc-ppocr
     install-share
     install-gettext
+    install-qtclient
 ;
 alias exe     : rdpproxy rdpclient rdpinichecker ;
 alias libs    : libredrec ;
 
+import notfile ;
+notfile post_qtclient : @my-post-command : libs exe ;
+actions my-post-command
+{
+    echo my-post-command $(tbuildcmd) runs.
+    cd projects/qtclient ;
+    bjam $(tbuildcmd) ;
+    cd ../.. ;
+    rsync -aP projects/qtclient/bin/gcc-9/$(tbuildcmd)/. bin/gcc-9/$(tbuildcmd)/
+}
+
 alias ocr_tools : display_learning extract_text ppocr_extract_text ;
 
 alias install-etc-ppocr : install-etc-ppocr-latin install-etc-ppocr-latin-cyrillic ;
@@ -199,6 +232,39 @@ install install-lib
     : <location>$(INSTALLDIR)$(LIB_PREFIX)
     ;
 
+import path : basename ;
+
+#epath = "$(REDEMPTION_ROOT_PATH)/projects/qtclient/bin/gcc-9/release/qt5client" ;
+#ename = basename ( $(epath) ) ; # nope, causes target to not be found :(
+# adds newline at end
+#ename = [ SHELL "basename $(epath)" ] ;
+#ename = SHELL "basename $(epath)" ; # does not work
+actions make_qtclient_install
+{
+    echo "make_qtclient_install: REDEMPTION_ROOT_PATH $(REDEMPTION_ROOT_PATH) PWD $(PWD:E=not_set)" ;
+    echo [ SHELL "pstree -s -p $$ && echo PID $$ PWD $PWD" ] ;
+    # unfortunately, when we get here, bjam is not called with debug or release, so tbuildcmd is empty
+    # so assuming we delete our directories manually:
+    # rm -rf bin/gcc-9/* projects/qtclient/bin/gcc-9/* debian/* ./bin/project-cache.jam ./projects/qtclient/bin/project-cache.jam
+    # we can count on only one qt5client being built in qtclient bin dir, so target it with wildcards
+    # also, debian/buildtmp/usr/local/bin/ $(INSTALLDIR)$(BIN_PREFIX)/ might not exist at this time
+    # so use install instead of cp
+    # don't use local here, crashes "not in a function"
+    # cannot get the stupid glob to work, write manually
+    #epath = [ glob "$(REDEMPTION_ROOT_PATH)/projects/qtclient/bin/gcc-9/*/qt*client" ] ;
+    #epath="$(REDEMPTION_ROOT_PATH)/projects/qtclient/bin/gcc-9/release/qt5client" ;
+    #ename = [ SHELL "basename $(epath)" ] ;
+    #ename=`basename $(epath)`
+    # don't bother with variables, nothing works here https://stackoverflow.com/questions/75342602/bjam-cannot-assign-a-literal-to-a-variable
+    #echo "epath $(epath) ename $(ename)" ;
+    #cp -av $(REDEMPTION_ROOT_PATH)/projects/qtclient/bin/gcc-9/*/qt*client $(INSTALLDIR)$(BIN_PREFIX)/ ;
+    # just type everything verbatim:
+    echo install -m 775 -D $(REDEMPTION_ROOT_PATH)/projects/qtclient/bin/gcc-9/release/qt5client $(INSTALLDIR)$(BIN_PREFIX)/qt5client ;
+    install -m 775 -D $(REDEMPTION_ROOT_PATH)/projects/qtclient/bin/gcc-9/release/qt5client $(INSTALLDIR)$(BIN_PREFIX)/qt5client ;
+}
+explicit install-qtclient ;
+make install-qtclient : : @make_qtclient_install ;
+
 
 exe redrec
 :

首先,我们想知道我们是在做调试还是发布构建;显然在bjam中这是一个“变体”,也是一种“特性”,我不知道如何读取它(Getting the build type/variant inside a bjam Jamfile / echo a feature?),所以我做了一个变通方案,使用命令行参数-当然,只有当你使用bjam命令,并在命令行中显式地包含debugrelease时,这才是好的。
然后,notfile被用来定义类似于新的、自定义/手动目标的功能--在某种意义上,我们可以调用post_qtclient,它将触发libsexe作为依赖项的构建;然后运行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

diff --git a/packaging/template/debian/rules b/packaging/template/debian/rules
index 014c470e4..dab9a70ea 100755
--- a/packaging/template/debian/rules
+++ b/packaging/template/debian/rules
@@ -32,7 +32,8 @@ build:
        # dh_testdir - test directory before building Debian package. It makes sure
        # that debian/control exists also check Jamroot for redemption project.
        dh_testdir Jamroot
-       bjam -q $(BJAM_EXTRA_INSTALL) exe libs
+       #bjam -q $(BJAM_EXTRA_INSTALL) exe libs
+       bjam -q $(BJAM_EXTRA_INSTALL) post_qtclient

...这最终会生成一个.deb文件,该文件中的子项目可执行文件与此过程的其他可执行文件位于同一个bin文件夹中。
请注意,由于缓存的原因,从头开始重建项目可能会很棘手,所以我在这里执行了以下命令来“清理所有内容”:

rm -rf bin/gcc-9/* projects/qtclient/bin/gcc-9/* debian/* ./bin/project-cache.jam ./projects/qtclient/bin/project-cache.jam

好吧,希望这就是问题所在...

相关问题