bjam - build subfolder project (change directory to subfolder project before build) - gcc

I am trying to build https://github.com/wallix/redemption, which uses bjam. I don't really know bjam (and I think, given that I already don't really know make and cmake, I don't really have that much space left in in my head for yet another build system language).
More specifically, I want to build projects/qtclient in there, as part of the main project; so that when I run tools/packager.py (which repeats the bjam build process from scratch), i also get the qtclient executable in the generated .deb.
Note that, when I'm the root directory of the repository, for the main build, I can do:
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
...
... and it works. If I try to build the projects/qtclient from the same directory location, it fails:
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
... but if I change directory to projects/qtclient first, and call bjam qtclient (or just bjam) there, it works:
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...
Right - so this shows me, that the error 'ERROR: rule "setvar" unknown in module "Jamfile</home/USER/src/redemption_git/projects/qtclient>".' is due to bjam running in the "project root" directory, and not in the projects/qtclient subdirectory.
So, now I try to integrate the build of projects/qtclient inside the main Jamroot; I've tried adding qtclient at end of alias exe line (before the semicolon):
alias exe : rdpproxy rdpclient rdpinichecker qtclient;
Result: build does not even start:
redemption.git$ bjam libs exe
error: Unable to find file or target named
error: 'qtclient'
error: referred to from project at
error: '.'
And I've tried adding projects/qtclient at end of alias exe line :
alias exe : rdpproxy rdpclient rdpinichecker projects/qtclient;
Result: build starts, but fails as bjam does not run in the project subdirectory (same error: 'ERROR: rule "setvar" unknown in module'):
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
...
As per Boost-build - dependency on subproject target I also tried modifying the code so it has this, while restoring the original alias exe line:
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 ;
... and again, build starts, but fails as bjam does not run in the project subdirectory (same error: 'ERROR: rule "setvar" unknown in module'):
$ 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
...
Also, as per How to build multiple targets with Boost and Jamroot? I've tried adding reference to projects/qtclient/Jamroot at end of alias exe line:
alias exe : rdpproxy rdpclient rdpinichecker projects/qtclient/Jamroot;
This actually runs and build completes without errors - however there is no mention of "qtclient" anywhere in the build log, and the corresponding executable does not get generated.
The same happens for build-project that I got from bjam - how to always execute shell script before building a target?:
build-project projects/qtclient//qtclient ;
... or for
build-project projects/qtclient ;
I also tried to cheat and just call from the shell:
Echo [ SHELL "cd projects/qtclient; bjam release qtclient" ] ;
... this indeed builds qtclient - but then erases the build folder, before starting to build the main project :(
So - how do I have bjam compile an extra project in a subfolder, as part of the main project, correctly (meaning that bjam would change the current working directory to the subfolder, before attempting to build the extra project)?

EDIT: the procedure described below, while it adds the subproject executable so it runs correctly after installing, it also messes up paths for executables from the main project. A correct procedure has been provided by developers of the original project in this comment:
But if you want, you can add cd projects/qtclient; bjam qtclient / cd projects/qtclient; bjam install in packaging/template/debian/rules, add the dependencies in the packaging/targets/ files and the new executable in packaging/template/debian/redemption.install (the last step may be useless thanks to %PREFIX%/bin/*).
Right, so this was a more complicated thing, and I came to a nasty workaround - but, better than nothing. There were several problems here - first, let's look at the Jamroot of the subfolder project; I'll post this as a diff:
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 :
Originally, it tried to find REDEMPTION_PUBLIC_PATH via [ SHELL "readlink -n -f ../.." ] ; - and if a shell is being called with readlink -f ../.., it has no other choice but to refer to its CWD; it does not "know" whether it is in a subfolder of a project. Luckily, it turns out there is a bjam syntax that lets a jam file find its own path: the path-constant rule (boost-build/bjam constant for path to Jamroot), and that is what the above change uses, to provide a correct reference to _INCLUDE_PATHs and included files - which gets rid of the "ERROR: rule "setvar" unknown in module".
Once this is done, the next problem is, that if the build of the subfolder project is called from the main Jamfile (e.g. via build-project), we'll get a new error:
/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"
The problem is that both the main Jamroot and the subproject Jamroot do include $(JAM_INCLUDE_PATH)/cxxflags.jam ; etc; I tried removing those manually from the subproject Jamroot, for the case when build is started from the main folder - but then eventually we get to the subproject jam complaining about unknows stuff:
/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>".
... so it still needs those files, but they are already in conflict ... so this way won't work.
So again we have to go back to "changing directory", and apparently we must do that from the shell ... So that part is in the main Jamroot, again shown as a 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
:
First, we'd like to know whether we're doing debug or release build; apparently in bjam this is a "variant" which is a type of "feature", and I couldn't figure out how to read it ( Getting the build type/variant inside a bjam Jamfile / echo a feature? ). So I made a workaround where command line arguments are used - of course, this is only good when you use a bjam command that explicitly includes debug or release on the command line.
Then, a notfile is used to define something that functions like a new, custom/manual target - in the sense that we can call post_qtclient and it will trigger the build of libs and exe as dependencies; and then the my-post-command action is ran. The commands in this action run in the shell, so we can change directory to the subfolder project, run bjam in debug or release (via variable), and once done, we copy all files form the subfolder project bin directory to the main bin directory.
This is good enough for a build via bjam -a release post_qtclient - but not good enough if you intend to run debhelper scripts to build a .deb package (done by a tool in this repository, ./tools/packager.py --build-package --force-build).
To do that, we must copy the resulting executable file of the subfolder into the right install location; that is done by the install-qtclient "make" action (or whatever that is). It is very tricky to handle string there (left comments to document that) - so in the end, this part does a copy of the hardcoded subfolder project executable into the "bin" install location, as for other executables - however, using install, since at the time this piece runs, $(INSTALLDIR)$(BIN_PREFIX) might not yet exist!
This generally takes care of the install part; and to finally make sure that the subproject executable does end up in the .deb file, change /packaging/template/debian/rules like so:
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
... and this should finally result with a build of a .deb file, that has the subproject executable in the same bin folder as the other executables that are products of this process.
Note that rebuilding the project from scratch might be tricky because of caching, so here I've done the below command to "clean everything":
rm -rf bin/gcc-9/* projects/qtclient/bin/gcc-9/* debian/* ./bin/project-cache.jam ./projects/qtclient/bin/project-cache.jam
Well, hope that was it for this problem ...

Related

Is there a Buildroot setting for making kernel source available to compile against?

I've been given a .zip file containing source for a proprietary kernel module. Once unzip'd, there is an install script that needs to be run. The install script untar's the actual source and builds the kernel module. It requires kernel headers to compile against.
Here is my Buildroot .mk file:
FOOCO_VERSION = 1.0
FOOCO_SOURCE = cust_kernel_drvr.zip
FOOCO_SITE = /mnt/third-party/fooco
FOOCO_SITE_METHOD = local
define FOOCO_CONFIGURE_CMDS
unzip $(#D)/$(FOOCO_SOURCE) -d $(#D)
endef
define FOOCO_BUILD_CMDS
chmod +x $(#D)/TOOLS/Linux_x64/DRIVER/install
cd $(#D)/TOOLS/Linux_x64/DRIVER; $(SHELL) ./install
rm -rf $(#D)
endef
$(eval $(generic-package))
This results in the following log output and error:
(Note: I enabled debugging that shows the start and end of each step.)
DEBUG: start | rsync | fooco
>>> fooco 1.0 Syncing from source dir /mnt/third-party/fooco
rsync -au --chmod=u=rwX,go=rX --exclude .svn --exclude .git --exclude .hg --exclude .bzr --exclude CVS /mnt/third-party/fooco/ /root/buildroot-2022.02.1/output/build/fooco-1.0
DEBUG: end | rsync | fooco
DEBUG: start | configure | fooco
>>> fooco 1.0 Configuring
unzip /root/buildroot-2022.02.1/output/build/fooco-1.0/cust_kernel_drvr.zip -d /root/buildroot-2022.02.1/output/build/fooco-1.0
Archive: /root/buildroot-2022.02.1/output/build/foofo-1.0/cust_kernel_drvr.zip
[snip]
creating: /root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/
creating: /root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/DRIVER/
inflating: /root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/DRIVER/install
inflating: /root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/DRIVER/cust_kernel_drvr-1.2.0.15-0.noarch.rpm
inflating: /root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/DRIVER/cust_kernel_drvr.tar.gz
inflating: /root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/DRIVER/license_gpl.txt
[snip]
DEBUG: end | configure | fooco
DEBUG: start | build | fooco
>>> fooco 1.0 Building
chmod +x /root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/DRIVER/install
cd /root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/DRIVER; /bin/bash ./install
Extracting archive..OK!
Compiling the driver...Error: make[1]: Entering directory '/root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/DRIVER/fooco_cust/src/linux/driver'
common.mk:82: *** Kernel header files not in any of the expected locations.
common.mk:83: *** Install the appropriate kernel development package, e.g.
common.mk:84: *** kernel-devel, for building kernel modules and try again. Stop.
make[1]: Leaving directory '/root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/DRIVER/fooco_cust/src/linux/driver'
Error: unable to find driver file (fooco_cust.ko) in /root/buildroot-2022.02.1/output/build/fooco-1.0/TOOLS/Linux_x64/DRIVER/fooco_cust/src/linux/driver
rm -rf /root/buildroot-2022.02.1/output/build/fooco-1.0
DEBUG: end | build | fooco
touch: cannot touch '/root/buildroot-2022.02.1/output/build/fooco-1.0/.stamp_built': No such file or directory
make: *** [/root/buildroot-2022.02.1/output/build/fooco-1.0/.stamp_built] Error 1
package/pkg-generic.mk:289: recipe for target
'/root/buildroot-2022.02.1/output/build/fooco-1.0/.stamp_built' failed
I found that the make files that came with the kernel module are looking in several places for the kernel headers:
/lib/modules/${BUILD_KERNEL}/source \
/lib/modules/${BUILD_KERNEL}/build \
/usr/src/linux-${BUILD_KERNEL} \
/usr/src/linux-$(${BUILD_KERNEL} | sed 's/-.*//') \
/usr/src/kernel-headers-${BUILD_KERNEL} \
/usr/src/kernel-source-${BUILD_KERNEL} \
/usr/src/linux-$(${BUILD_KERNEL} | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/') \
/usr/src/linux \
/usr/src/kernels/${BUILD_KERNEL} \
/usr/src/kernels
Why is the kernel source not visible to this build? I thought that, since Buildroot is building the kernel as part of the overall process, the header files would be available for subsequent kernel module compiles. Am I missing a setting? I feel that I'm not understanding the Buildroot process in a basic way, even after referring to the manual many times.
I'm using Buildroot 2022.02.1 and kernel 5.15.33.
Your download/extract logic is very convoluted. You should really use something like this:
FOO_SITE = /mnt/third-party/fooco
FOO_SOURCE = cust_kernel_drvr.zip
FOO_SITE_METHOD = file
define FOO_EXTRACT_CMDS
unzip $(FOO_DLDIR)/$(FOOCO_SOURCE) -d $(#D)
endef
Regarding the build issue: it is impossible to help without studying the specific build system of this kernel module. Very likely you will need to pass some environment variables to tell the build system where your kernel source code is located, and possibly other things. But without looking at the specific details, it's impossible to help you.
You can have a look at how standard out of tree kernel modules are handled by looking at the package/pkg-kernel-module.mk code. However, that will not be directly useful to a package like yours that uses a custom installation script.
The magic was the LINUX_DIR variable which, according to Buildroot user manual:
contains the path to where the Linux kernel has been extracted and built.
I was able to patch the install script to send this variable to the make file that was looking for the kernel.

Where's the location of the app/binary defined in a yocto recipe?

I have a following recipe which runs a said service which in turns runs an app on boot-up, but I am trying to understand where the location of the app defined which ends up in sysfs image.
Currently, the appSource binary (defined in Makefile) gets stored in /usr/bin but I'm not sure where the destination location (/usr/bin) is defined.
The following command results in
$ bitbake -e appSource | grep ^FILES_${PN}
FILES_appSource="/usr/bin/* /usr/sbin/* /usr/libexec/* /usr/lib/lib*.so.* /etc /com /var /bin/* /sbin/* /lib/*.so.* /lib/udev /usr/lib/udev /lib/udev /usr/lib/udev
Here's the recipe
inherit autotools-brokensep pkgconfig
DESCRIPTION = "A sample recipe"
LICENSE = "CLOSED"
DEPENDS = "glib-2.0"
FILESPATH =+ "${THISDIR}:"
SRC_URI = "file://appSource"
S = "${WORKDIR}/appSource""
FILES_${PN} += "${systemd_unitdir}/*"
INIT_MANAGER = "systemd"
do_install_append() {
if ${#bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
install -d ${D}/etc/initscripts
install -d ${D}${systemd_unitdir}/system
install -m 0644 ${WORKDIR}/appService/appService.service ${D}${systemd_unitdir}/system/appService.service
install -d ${D}${systemd_unitdir}/system/multi-user.target.wants/
ln -sf ${systemd_unitdir}/system/appService.service ${D}${systemd_unitdir}/system/multi-user.target.wants/appService.service
fi
}
Here is what I find out:
You are inheriting autotools-brokensep which has the following content:
# Autotools class for recipes where separate build dir doesn't work
# Ideally we should fix software so it does work. Standard autotools supports
# this.
inherit autotools
B = "${S}"
So, it inherit autotools which has do_install with the content of:
autotools_do_install() {
oe_runmake 'DESTDIR=${D}' install
# Info dir listing isn't interesting at this point so remove it if it exists.
if [ -e "${D}${infodir}/dir" ]; then
rm -f ${D}${infodir}/dir
fi
}
So, it runs the install target of your Makefile into ${D} which is ${WORKDIR}/image.
So, I assume that your Makefile has an install target that copies the binary into /usr/bin.
For the FILES variable content, this is defined in bitbake.conf:
FILES_${PN} = "${bindir}/* ${sbindir}/* ${libexecdir}/* ${libdir}/lib*${SOLIBS} \ ...
Provide your Makefile to confirm my assumption, or I do a further research on the topic.

bjam - how to always execute shell script before building a target?

My aim is to build a library which includes version information.
I have a script which will update ./version.cpp only when the version has actually changed. This to prevent unnecessary rebuilds.
I have a lib target which globs *.cpp, which is inclusive of version.cpp.
The problem is that if I run bjam I can see it execute the script, and update version.cpp, but the library is not rebuilt.
Only when I run bjam again does it see that version.cpp has changed, and rebuild the lib
My jam file:
Echo [ SHELL "./write_version.sh" ] ;
lib foo
: [ glob *.cpp ]
;
Output of running bjam (twice):
$ bjam
Updating version.cpp
...found 119 targets...
$ bjam
...found 121 targets...
...updating 3 targets...
gcc.compile.c++ ../foo/bin/gcc-4.8/debug/link-static/version.o
gcc.archive ../foo/bin/gcc-4.8/debug/link-static/libfoo.a
...updated 3 targets...
Question:
How can I get both the script and the library build working together?
The issue is that dependencies are resolved when the Jamfile is loaded
ie: in the example Jamfile:
lib foo
: [ glob *.cpp ]
;
the cpp files are globbed and stat'd when the Jamfile is loaded. Any that aren't out of date won't be rebuilt.
After loading the Jamfile, bjam executes the script which generates the updated version.cpp, which is too late.
A work around is to execute the shell script in the Jamroot. In this way version.cpp is updated before the Jamfile which uses it is loaded. The file is stat'd, found to be updated, and lib foo rebuilt.
Jamroot:
Echo [ SHELL "./write_version.sh" ] ;
build-project foo ;
foo Jamfile:
lib foo
: [ glob *.cpp ]
;

Building FTP4ALL: undefined reference to `crypt'

I know - there is a lot of question like this one - but can't find solution...
Trying to install FTP4ALL 3.012 on CentOS 6.
/configure executed normally, but make - returns me error:
f4adp_user.o: In function `f4adp_usr_pwd':
f4adp_user.c:(.text+0xfa0): undefined reference to `crypt'
f4adp_user.o: In function `f4adp_usr_chg':
f4adp_user.c:(.text+0x340e): undefined reference to `crypt'
f4adp_user.o: In function `f4adp_usr_adq':
f4adp_user.c:(.text+0x37a7): undefined reference to `crypt'
serverd.o: In function `user_request_login_permission':
serverd.c:(.text+0x2a9a): undefined reference to `crypt'
collect2: ld returned 1 exit status
Makefile contains only:
$ cat Makefile | tail -n 15
all:
#cd src ; make
strip:
#cd src ; make strip
clean:
#cd lib ; make clean
#cd src ; make clean
#cd cfg ; make clean
#rm -f Makefile src/common/tweak.h src/common/Makefile src/Makefile src/ftpa/Makefile src/ftpd/Makefile src/ftps/Makefile
install:
cp -f bin/* /usr/local/bin
How can I fix it?
You need to add -lcrypt to your link line so the linker will search the crypt for the crypt function.
In normal Unix tool chains, things flow like this:
Source code (compiler) -> assembly code (assembler) -> .o files -> (linker) -> executable.
The linker, which is the last part of the tool chain, is responsible for combining all of your functions into an executable. Somewhere in your Makefile, most likely the Makefile in your src subdirectory, there will be a line that tells the linker where to find all of the .o files, and any dependent libraries. That's you link line, and it needs to have -lcrypt so that it can find the crypt function.
Regarding FTP4ALL only - solution is:
$ vim ../../ftp/ftp4all/configure
where ftp4all is directory, which was created after:
$ tar xfp ftpd-3.012.tar.gz`
Find lines:
echo $ac_n "| want DES encryption (y/n) ? $ac_c"
Edit:
else
DES=""
LIB=${LIB}
fi
To:
else
DES=""
LIB=${LIB}" -lcrypt"
fi
Also, after this - I got another error when compile:
common.c:52: error: conflicting types for ‘setenv’
/usr/include/stdlib.h:585: note: previous declaration of ‘setenv’ was here
Solution:
$ vim ./src/ftps/common.c
Comment with /* and */ lines:
#ifndef HAVE_SETENV
/*
void setenv(char* var, char* val, int new)
{ char str[256];
sprintf(str,"%s=%s",var,val);
putenv(str);
}
*/
#endif /* HAVE_SETENV */
Now - it works.
P.S. Please note, that:
FTP4ALL is no longer maintained. This web site is only for historic
purposes. Visit the successor project OpenFTPD instead.
Hope - nobody else will try install it :-)

gcc : directory : No such file or directory

I am trying to build the mali driver for linux 3.7 kernel from Here.
There is a separate build script like,
#!/bin/bash
export KDIR=/path/to/kernel/dir/
..
..
gcc -v//Just for testing purpose printing gcc version
make
gcc -v
...
Actual host machine has 2.6 kernel, but im instructing make to use linux 3.7 kernel. The above make will call the Makefile of mali driver's makefile.
For the above script,
gcc version prints properly before and after make command, but when make entered in to kernel directory, gcc is not recognized.
it saying gcc : directory : No such file or directory.
same happens to arm-gcc too. Any Guess??
Edit:(make output)
make ARCH=arm -C /home/work/linux3.7/ M=/home/work/mali/driver/src/devicedrv/mali modules
make[1] : Entering directory `/home/work/linux3.7/`
gcc : directory : No such file or directory
gcc : directory" : No such file or directory
<command-line>: warning: missing terminating " character
gcc : directory : No such file or directory
gcc : directory" : No such file or directory
<command-line>: warning: missing terminating " character
gcc : directory : No such file or directory
gcc : directory" : No such file or directory
<command-line>: warning: missing terminating " character
gcc : directory : No such file or directory
gcc : directory" : No such file or directory
<command-line>: warning: missing terminating " character
CC [M] /home/work/mali/driver/src/devicedrv/mali/common/mali_kernel_core.o
.arm-none-linux-gnueabi-gcc: directory:No such file or directory
.arm-none-linux-gnueabi-gcc: directory":No such file or directory
make[2] : Leaving directory `/home/work/linux3.7/`
The problem is in drivers/gpu/vithar/ump/src/devicedrv/Makefile.common. It assumes that the vithar SDK has been pulled from SVN and has a valid SVN revision (it doesn't).
You have 2 options:
1) Edit the file above to skip invocation of svnversion:
- SVN_REV:=$(shell ((svnversion | grep -qv exported && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev$
+ SVN_REV=0
2) Add to make command line:
SVN_REV=0
gcc is recognized, found, and executed. The error "gcc: directory: no such file or directory" is given by gcc itself.
For some reason, gcc is trying to access "directory" (i.e., an object called "directory"), which does not exist.
Maybe a wrong expansion or an unexpected environment variable.
Try checking the appropriate Makefile and your make command.
For example, if you issued a command such as
KDIR="/usr/Linux Kernel directory" CONFIG=pb-virtex5 BUILD=release make
there is a risk that the system misinterpret KDIR, introducing two nonexistent objects "Kernel" and "directory" as well as an extra quotation mark. Such a possibility might explain the symptoms you observe. So, extra spaces in paths are definitely something worth checking.
You made a typo; you want
echo $(gcc -v)
but actually, for that coding
gcc -v
is enough.
You should be sure that gcc is correctly installed in your $PATH. Check with which gcc
addenda
If you suspect your Makefile is wrong, use remake to debug it. Often, just running remake -x in a terminal could be enough to understand what is happening.
Perhaps you are passing some weird argument to gcc ? Or some wrong #include?

Resources