Cross-compile with relative pathnames - for binary portability/embeddability? (GCC) - gcc

Say I am creating an application bundle with some scripts, maybe a daemon, or even a helper binary... When compiling such a binary.. is it feasible to ./configure/make it with only relative paths? For example, a more conscientious Makefile will include for provisions such as...
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
--datadir=DIR read-only architecture-independent data [DATAROOTDIR]
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
--docdir=DIR documentation root [DATAROOTDIR/doc/hiawatha]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
--psdir=DIR ps documentation [DOCDIR]
This is great, you can install everything to /opt/local instead of /usr/local. Maybe even go crazy, and rename the binaries via sed.. I get it..
But what remains unclear in my tiny brain, is if the ability to arbitrarily set paths in such a manner extends to the ability to map the directories relative to the executable, in a manner similar to...
--prefix=PREFIX install architecture-independent files in PREFIX [/usr/local]
--prefix=./ aka [../relative/to/binary]
So, for example, no matter where you launched the bin from, it would always know that it's .conf file was going to be up one folder, in the that relative ../etc folder, or possibly even right next to it, in the same directory, ./. Similarly, you could guarantee write access to log and pid files, etc, without wondering about your target's permissions/directory structure...
This would enable a completely portable /bin /etc /lib /var directory structure, within a PATH to which I can guarantee some semblance of predictability... but I don't think it just "works" like that.. And I am unsure if simply "linking statically" or otherwise ? truly creates binaries that are able to be moved to another system (albeit, for this scenario, to ones with the same support libs in the same places, so as not to muddle the issue) Is it possibly to cross-compile in this manner? And can you build for multiple architectures in the same build cycle? (For example i386 AND x86_64 at the same time)
Maybe I could just use a recommendation of a good GNU/GCC primer ( CC, CFLAGS, LDFLAGS, -l, , -I , and CPP 101, etc.) but that wasn't written for (and by) Math teachers - in the 70's?

In full generality, no, that won't work. There are things in /etc for example that are expected to be shared by the whole system and won't work correctly if you're trying to keep a private copy for one app.
With that said, your app probably isn't using every single shared resource on the system. Either using a local /bin and /sbin, or symlinking to the real ones from a relative path within your app's directory should be fine. /var seems less likely as something that your app needs to know about directly - anything stopping you from storing logs your own way, or using syslogd?

Related

Compile OCCT7.5 with rapidjson using FreeCad Libpack?

I'm looking to compile OCCT 7.5 in Windows 10 (x64 via VS2019) for use with FreeCAD, to enable exporting glTF files, which requires RapidJSON support (in OCCT). I've checked out OCCT 7.5.3 and RapidJSON 1.1.0 from their git repos, then grabbed the FreeCAD libpack 12.5.2 (for OCCT 7.5). I started from FreeCAD's build docs, then attempted to follow OCCT's build docs.
When configuring the OCCT project in CMake-GUI, I've been able to find what I think are correct values for some variables (e.g. those regarding FREETYPE) within the FreeCAD libpack, as well as RapidJSON, but still get some errors in the config, seemingly no matter what values I try:
Could not find headers of used third-party products:
3RDPARTY_TCL_INCLUDE_DIR 3RDPARTY_TK_INCLUDE_DIR
...
Could not find DLLs of used third-party products: 3RDPARTY_TCL_DLL_DIR
3RDPARTY_TK_DLL_DIR
I've tried using *.lib, *.h and *.dll files found within the FreeCAD Libpack (and their corresponding directories) for *_LIBRARY/INCLUDE/DLL variables, but nothing is found. I see
Info: TCL is used by OCCT
Could NOT find Tclsh (missing: TCL_TCLSH)
even though tclsh86t.exe exists in the libpack/bin directory.
What should the 3RDPARTY_TCL_* & 3RDPARTY_TK_* CMake variables be set to, to use the FreeCAD libpack?
The problem was my lack of familiarity with CMake and Cmake-gui: the gui opened a dialog for a FILEPATH when specifying a PATH variable. I naively thought, "I don't know CMake, so I'll trust the gui". Totally wrong.
I manually edited the 3RDPARTY_* variable entries to point to the correct directories (or libs, when needed) in the FreeCAD libpack, using the variable name and description/hint for each to determine what the variable's value should be. Below are my entries, for reference:
I did need to check "Advanced", to edit the FREETYPE_LIBRARY_DEBUG & FREETYPE_LIBRARY_RELEASE variables (CMake set them to separate libs found in a jdk directory, presumably because it was added to the system path at some point).

How to get SCons StaticLibrary store the library file in another folder

I'm using scons for a build project. I want to make a static library from object files that reside a different directory and surprisingly I'm not able to do that. Here is a snippet of the code I'm using:
OBJECT_FILES = env.Object('main.o', 'main.cpp')
env.StaticLibrary("../mylib", OBJECT_FILES)
StaticLibrary doesn't work if I put any directory above this directory even if I use absolute path. For the current directory or any other directory under the current directory, this works with no issues.
Here's how I'd do that..
env.StaticLibrary("../${LIBPREFIX}mylib${LIBSUFFIX}", 'main.cpp')
No need to explicitly request env.Object() SCons will figure out the correct thing to do here. Unless for some reason you want to later do something with that list of Object()'s.
When you specify
env.StaticLibrary("mylib", ['main.cpp'])
SCons will automatically prepend $LIBPREFIX and append $LIBSUFFIX to mylib and on a POSIX system you'd end up with libmylib.a on Windows you'd end up with mylib.lib
Please consider joining the SCons discord server for more "live" help and discussions.

Workaround for an API not allowing require a specific library (luasocket) and not able to include it via moving DLL

I am using an API called Piepan, which allows me to write Lua scripts for Mumble bots. For context, it is written in Golang using an alternative mumble implementation called Gumble. Piepan scripts are executed via cmd prompt through a piepan.exe.
I can require most libraries, like inspect.lua, and I can easily require luasocket in non-piepan scripts (scripts executed via lua.exe), but if I try to require luasocket (or what I really want, a redis library that depends on luasocket), I get an error. This is less of an error and more of a missing feature from the API, which the creator acknowledges. The creator suggests to someone else with this problem that they simply use Gumble, but I cannot do that as I am only a Lua programmer.
Here's the code of me just trying to require luasocket:
local socket = require ("include-test.socket")
(I've also tried include-test.socket.core and just socket.core)
In accordance with this stackoverflow answer, I moved my files to resemble the user's own directory, so it looks like this:
Piepan folder
-piepan exe and dlls (not luasocket dlls)
-include-test (folder)
--Script for piepan
--socket.lua
--socket folder
---core.dll
Despite the directory looking how I imagine it should based on other users' Q/As, I get this error:
.\include-test\socket.lua:13: module socket.core not found:
no field package.preload['socket.core']
Lstat : The system cannot find the path specified.
GetFileAttributesEx .\socket\core.lua: The system cannot find the path specified.
GetFileAttributesEx C:\Users\Michael\piepan\lua\socket\core.lua: The system cannot find the path specified.
GetFileAttributesEx C:\Users\Michael\piepan\lua\socket\core\init.lua: The system cannot find the path specified.
GetFileAttributesEx C:\Program Files (x86)\Lua\5.1\lua\socket\core.luac: The system cannot find the path specified.,
I've also tried including the following line, inspired by this stackoverflow answer.
package.cpath = package.cpath .. ';include-test/?.dll'
to no avail.
I am looking for any available solution, whether that be moving around dlls or compiling the original Piepan w/ extra files as needed.
(To clarify, I need a workaround that allows me to require the redis library within the same script I run through piepan. Using an outside script with the redis library to then, say, launch piepan and do something there, is not helpful to me.)

How do I generate loadable modules during Linux kernel build?

I seem to successfully build a kernel image, but I can not generate all the modules I expect. I expect more modules since I see them enabled in the gconfig window. Here is a copy of my make session. Seems like make goes into the devices directories. I can not figure out why it is not create the .ko files. I expect to see .ko files. I have checked the Makefile in /drivers directory, and I can see that it is configured with a number of lines like
obj-$(CONFIG_PCI) += pci/
Which directs make to build the pci module for instance. I think this implies that I should see a number .ko files. But I do not. I have seen just one .ko file for scsi module. I like to be able to build all of modules selected.
I also verified that a number of mudules are enabled when I issued:
make VARIANT_DEFCONFIG=msm8974_sec_hlte_spr_defconfig msm8974_sec_defconfig SELINUX_DEFCONFIG=selinux_defconfig gconfig
But as I said, I do not see any of them. What am I missing please?
#Subin - Thanks. I just tried make modules_install. I have to mention that I am cross compiling this for an arm target. I believe modules_install is for the purpose of installing the driver for the machine you are on? I got a message about needing to be in root, and I did not proceed. I have been wondering when I need to run it. What does it do exactly please?
Re: the make modules; I have run it before. I'll run it again and post the result. Since I got one .ko file I figured the issue is something different between that one module, and every other one enabled in my config. Here is what I got when I ran make modules:
sansari#ubuntu:~/WORKING_DIRECTORY$ make modules
CHK include/linux/version.h
CHK include/generated/utsrelease.h
make[1]: `include/generated/mach-types.h' is up to date.
CALL scripts/checksyscalls.sh
Building modules, stage 2.
MODPOST 1 modules
Re: your comment on the location of .ko files, I am doing a find to see if perhaps I am not looking at the right place, it only finds the one which was built. Not the other ones. Here is the output:
sansari#ubuntu:~/WORKING_DIRECTORY$ find . -type f -name "*.ko"
./drivers/scsi/scsi_wait_scan.ko
sansari#ubuntu:~/WORKING_DIRECTORY$
Should I perhaps run make v=1, in verbose mode that is? Would that provide more information on why the other modules are not built?
#Gil Hamilton - Thanks. You are right. Here is an excerpt of the .config file:
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
# CONFIG_BLK_DEV_SR is not set
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=y
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_WAIT_SCAN=m
This entry is the only one set to 'm'.
Most device driver modules in the linux kernel build system use a tristate (3-valued) configuration setting. The options are
'n' (don't build at all),
'y' (build and link statically into the main kernel object), and
'm' (build as module for dynamic loading).
The values are determined by the content of .config. The values in .config are usually generated from an existing config file (look in arch/<ARCH>/configs for your <ARCH>). Also check the output of 'make help' for interesting configuration targets.
If you're not seeing the .ko files being created, that indicates the corresponding configuration variable is either set to 'y' or 'n'.

[ Bison ]Is it possible to customize runtime data dir or specify a relatif path in config of compilation?

I am doing the build local of Bison(Linux), to provide it to other team to use.
I need to download its source from homepage and build it local, then install etc... but problem is that, after we build it(its lib/bin ..), the user of it need to use it at other pc(rather than the same host than us).
I notice that, at the build/install for Bison, we need to specify the path like datarootdir etc for the .configure, which provides an absolute path into the build and which used later in runtime for binary of Bison. (dir inside 'Share' for instance).
But since this path in build we specified would be different from the people(user)'s host's real dir. (the lib/bin are rsync later to other ppl's pc) Then this path of my local would not work for them.
My question is that, is it possible to specify a relatif path while compile/install Bison,(for example relatif to Bison binary etc). Or while using the binary of Bison, is it possible to customize the datadir etc for it?
So this could be more flexible at the user side later? if else we have to provide the same dir structure exact the runtime onw as the built one.
Thanks folks!
You can override the data path with the following:
BISON_PKGDATADIR=/some/other/path/share/bison

Resources