How to install library from source code, without any config nor Makefile? - c

Sorry for what is likely a simple question -- still getting a handle on Linux.
I've been attempting to install the 'FreeMODBUS' library, however judging from the website, it is somewhat outdated. The download link leads to nowhere, however the source code is still accessible via Sourceforge as a .zip download. In the past I've only dealt with libraries that come via .tar, however the bigger issue is that there seems to be no config, makefile nor README detailing the installation process.
Additionally I tried including all of the source code and header files supplied within my Eclipse project. I was hoping that this would be the lazy man's solution to all of my problems -- or at the very least I could compile the .so file myself -- however I'm still getting 'undefined reference to [Function]' errors. From what I understand this is a linking issue. To the best of my knowledge all inclusions are correctly set up.
Is this library deprecated, or is there a step to the process that I'm overlooking? Thanks!
Some superfluous project information:
I'm using modbus for a C project. The network is ideally going to be setup so that a number of modbus enabled devices are configured on a single daisy chained RS-485 hub -- therein containing all our modbus communications to a single comm port in a rather complex system.
The problem however is that popular open source modbus library, 'libmodbus', doesn't appear to lend itself to this configuration. In order to instantiate a modbus node instance, it requires the comm port to be passed, as opposed to the unit's modbus id.

Related

How to dump an executable SBCL image that uses osicat

I have a simple common lisp server program, that uses the osicat library to interface with the posix filesystem. I need to do this because the system creates symbolic links to files, and uses the POSIX stat metadata, and neither of those things are straightforward to do in portable lisp.
I am managing the dependencies with quicklisp, and I have all of this pinned to a working distribution. The app is portable between CCL and SBCL, and I tend to build it in the first and deploy it using the latter. I declare the dependencies for the app with an asdf defsystem, and I can use quicklisp to load it for easy development from local projects.
For deployment I was just using some ansible playbooks that replicated a developer environment on a remote (.e. setting up quicklisp, pushing code into local projects, running out of a user home directory) which was hacky, but mostly ok. More recently, as it's becoming more stable I have been compiling it using sb-ext:save-lisp-and-die, using a simple compile script. This means I get an executable that I can run more like a server, with service management scripts, and an anonymous user account.
This has been working very well, and so I recently moved this step to the next level, and I'm building .deb packages with my compile script, so I can bundle up everything into a relocatable binary. This also sort of works, but the resultant binaries are not relocatable from the original build host. They refuse to start up, and it appears that they try to dynamically load a shared library for osicat
Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
Mar 15 12:47:14 annie [479]: {10005C05B3}>:
Mar 15 12:47:14 annie [479]: Error opening shared object "libosicat.so":
Mar 15 12:47:14 annie [479]: libosicat.so: cannot open shared object file: No such file or directory.
it looks like the image expects to find this in the original build tree's quicklisp archives
(ERROR "Error opening ~:[runtime~;shared object ~:*~S~]:~% ~A." "/home/builder/buil...quicklisp/dists/quicklisp/software/osicat-20180228-git/posix/libosicat.so
(SB-SYS:DLOPEN-OR-LOSE #S(SB-ALIEN::SHARED-OBJECT :PATHNAME #P"
so poking around the source, I realise that when quicklisp fetches osicat and exercise its build operation, it compiles this DLL to wrap it's interface with the system libaries, rather than just ffi to them directly - possibly because it's using cffi groveller, I don't really know much about cffi (yet). This is fine, but rather than linking to a .so using the system linker it's trying to dlopen it from a fixed path, which is not very portable, and kind of breaks the usefulness of save-image
I'm a bit stumped at this point, but before I go diving any much further into QL and cffi builds, I wondered if there's some build or compile configuration I'm missing that would make it bootstrap in a more 'static' fashion or influence the production of the wrapped library. Ideally I just want a single blob I can wrap in an installer, and link it against system libraries, but if I have to deploy some additional artefacts that's probably alright. I don't know how to make the autogenerated shared objects occur at a more controlled path.
At that point though, I may as well write a .so for my posix calls and distribute this alongside the app and try and FFI to it more directly. That would be a bit of a pain, so I would prefer to not do this.
You're right, when a dumped image is starting up, it is trying to reload the shared libraries. Which, as you are experiencing, is not working if the image is not starting on the machine it was dumped on.
This is almost what static-program-op set out to solve. A simple system definition like this should help you compile a static program:
(defsystem "foo"
:defsystem-depends-on ("cffi-grovel")
:build-operation "static-program-op" ; "asdf" package is implied
:build-pathname "foo" ; path of the generated binary
:entry-point "foo:main" ; function to use as the entry point
;; ... everything else ...
)
If your system depends on grovel files (defined by :cffi-wrapper-file, :c-file or :o-file), such as the ones provided by osicat, then it will statically link those to your dumped image.
However, it's not perfect.
Essentially, there are still some issues. Some are being fixed upstream by CFFI itself (e.g. not reloading shared libraries of the statically embedded libraries), others are a bit harder. (E.g. SBCL default compilation options don't let you use static-program-op by default. This is being fixed in Debian builds of SBCL, but other distributions are being less responsive.)
This is obviously a problem that the community at large has met, and there are several libraries that are around to help:
The first one, that has been around for a while, is Deploy. The approach it takes is that it embeds the dumped image and the libraries into an archive, and rearranges things for the binary to load them from wherever it is extracted to.
The second one, which I am biased towards because I made it, is linux-packaging. It takes the approach of fixing static-program-op by extending it, but requires you to build a custom SBCL. However, it generates distribution packages like .deb and .rpm, in order to be able to specify dependencies for system shared libraries (e.g. if you depend on sqlite, it will figure out which package provides it and add it as a dependency in the .deb). I highly recommend looking at the .gitlab-ci.yml for examples.
I recommend reading the webpages of both of those libraries to make your choice, they both have their advantages and drawbacks. <joke>Obviously, linux-packaging is superior.</joke>
Maybe you can use sb-posix:symlink and sb-posix:fstat on SBCL instead, removing the osicat dependency by feature toggle.

undefined reference when calling code in downloadable kernel module

Following on from a previous question Using system symbol table from VxWorks RTP.
I am porting an existing vxworks kernel module to an RTP, however, much of the actual functionality is still embedded in other "downloadable" kernel modules. These are loaded using loadModule (as part of the startup process), and so should be in the system symbol table at the point my RTP runs.]
However, I cannot get my RTP to build, getting errors from the linker regarding undefined references.
How can I persuade the linker to ignore references to these functions? I am passing the -Xbind-lazy -non-static options to the linker.
As an example, the kernel module (built as database.out) might contain code such as
void writeDatabaseValue(int , char*);
and my RTP application code calls it in the usual way
void main (int)
{
//do some stuff
writeDatabaseValue(0,"foo"); //Linker error here
taskDelay(100); //but no linker error here
}
I have tried adding database.out to the link line using -l:database.out, which resolves the reference to writeDatabaseValue, however I then get into dependency hell, as the linker then tries to resolve all of database.outs references, including all of the standard vxworks api calls.
EDIT: Just for extra complication, some of the kernel module code I want to call is in the same module that actually spawned my RTP......
You are really trying to shoehorn one environment into a totally different one and are experiencing the pain inherent in this approach. I don't believe you will be able to get the linker to ignore the references.
Might be better to use symbolic links (available from within the Workbench environment) to source files and use those in a RTP project.
Or create dynamic libraries based on the DKMs (again, use symbolic links) and link those against your RTP.
As an example, let's say you have the following Workbench workspace:
DKM1
DKM2
RTP
Based on the question, you are attempting to link DKM1 & 2's object files in the RTP and are experiencing pain.
A better approach is to add a project link to the source files in DKM1 & DKM2 and have them compiled in the RTP. Because it is a link (instead of a copy) then changing the file in the DKM (to fix a bug for example) would also change it in the RTP.
In the RTP project, do a "New > Directory". Select the "advanced" button and check the "link to existing directory" then select the "DKM1" directory.
All the source file in the DKM1 will now be part of the RTP. Do the same with DKM2.
When you compile the RTP project, these new files should also be compiled.

Guide for steps to modify a filesystem in linux

I intend to make some changes to XFS filesystem.
Is there a documentation on the steps involved in doing so? I tried google but found nothing of much use. I have a rough understanding of the steps involved (see below), but I am looking for a detailed description so that I don't get stuck on simple things.
Steps in my mind:
Ensure my OS is not using XFS currently (no directories formatted as
XFS)
Download the source of XFS for my kernel version
Make changes to the source file
compile the modified source code (this step requires some conf files, which I am not sure where I can get from)
rmmod the xfs module and then insmod the xfs module so that changes are reflected in the system.
create a new partition, format it with XFS and test if things are alright after my changes.
Looking forward to some useful pointers.
Its OK if the pointers are for some other FS like ext3 or 4 as I believe the details would not vary from FS to FS.
Thanks
Your steps might work, but if you run into any issues you could wind up with an unbootable system.
The modules for the kernel must be built with the same version of compiler as the kernel itself or you'll have trouble. I've been stymied every time I tried to build a module for the kernel that came with the distro because the distribution maintainers invariably used some customized version of the compiler that I was not able to match.
A safer but longer option is install the kernel source package for your distro, and modify the XFS module source as necessary. Then build the entire kernel, including the customized XFS module, following the instructions for your linux distribution. Google for your distro and 'custom linux kernel', you should find dozens of hits.
Once built, you'll want to install your new kernel alongside your old one, and configure the bootloader to make the kernel selectable at boot time. This way even if something goes horribly wrong, you can still boot your system using your existing kernel.

unknown type name ‘gpgme_decrypt_result_t’ when trying to compile balsa

I've been trying to compile balsa the email reader on ubuntu (i'm new to the whole process of compiling an open source project directly from sources.
so i did the whole configure and make but then I ran into this problem:
error: unknown type name 'gpgme_decrypt_result_t
after doing a little research on the error code.. it turns out that it belongs to gpgme a scary looking encryption library..
what do I do in this case? i hope i'm not expected to go in the code and debug stuff am i?
update:
this question is related to this other question here on the ubuntu forum
Unfortunately, you may be required to delve into the code to figure out why something doesn't build!
In this case however the answer is probably quite simple. The main reasons I would expect a symbol from an external library to not have been defined are:
The library header files do not exist on your system
You have the wrong version of the library header files on your system
The headers exist, but the compiler is not looking in the correct place
Clearly the solutions are similar: you will need to install the correct version of gpgme's header files for this software in the right place. Note that having the library itself installed is not the same as having the headers. In Ubuntu this is evident due to the presence of -dev packages which are the package's header files, and if you look through the repose you will find libgpgme11-dev. I suggest you start by installing this, which will eliminate point 1 above. If it still doesn't work, you'll need to start investigating the other two possibilities.

Build a makefile dependency / inheritance tree

Apologies if I explain this badly or am asking something bleeding obvious but I'm new to the Linux kernel and kinda in at the deep end...
We have an embedded-linux system which arrives with a (very badly documented) SDK containing hundreds of folders of stuff, most folders containing a rules.make, make, make.config or some variation of... and the root folder containing a "master" makefile & rules.make which mean that you can, from the root folder, type "make sysall" and it builds the entire package.
So far so good, but trying to debug it is a bit of an issue as the documentation will say something like:
"To get the kernel to output debug messages, just define #outputdebugmessagesplz"
OK, but some of these things are defined in the "master" make/rules file, some of these are defined in the child make/rules/config files, some are in .h files... and of course it's far nicer to turn these things on/off from the "top" make.config rather than modifying individual .h files and then having to remember to turn them off again.
So I thought it would be a useful thing to recursively build a tree, starting from the master "make" file and following everything it does, everything that gets defined or re-defined, etc... but there doesn't seem to be a simple way of doing that?
I assume I am missing a "make" option here that spits this info out, or a usage of the makefile/config that will just work?
Your situation is not uncommon. When developing for embedded systems, you might encounter many custom systems that solve a problem in a specific way. As people already commented on your question, there's no easy way to generate a dependency graph for your makefile structure/framework. But there are some things you can try, and I'll try to base my suggestions based on your situation. Since you've said:
Im new to the Linux kernel and kinda in at the deep end...
and
We have an embedded-linux system which arrives with a (very badly
documented) SDK containing hundreds of folders of stuff
You could try the following things:
If your SDK is provided by a third-party vendor, try contacting them and get some support.
SDK's usually provide an abstraction to work with several components without a deep understanding of how each one of them really works. Try to pinpoint your problem, like if you want to customize only the kernel configuration, you could find the linux kernel folder on your SDK (assuming your SDK is composed of a set of folders with things like libraries, source code of applications and stuff, one of them might be the kernel one) and run make menuconfig. This will open a ncurses-based configuration GUI that you can navigate and choose kernel options.
As people already pointed out, you can try to run make -n and check the output. You could also try to run make -p | less and inspect the output, but I don't recommend this since it will only print the data base (rules and variable values) that results from reading the makefiles. You would have to parse this output to find out what you want in it.
Basically, you should try to pinpoint what you want to customize and see how this interacts with your SDK. If it's the kernel, then working only with it will give you a starting point. The linux kernel has its own makefile-build system, named kbuild. You can find more information about it at the kernel's Documentation folder.
Besides that, trying to understand how makefiles work will help you if you have a complex makefile structure controlling several components. The following are good resources to learn about makefiles:
GNU Make official documentation
O'Reilly's Open Book "Managing Projects with GNU Make"
Also, before trying to build your own tool, you can check if there's an open source project that does what you want. A quick search on google gave me this:
makegrapher
Also, check this question and this one. You might find useful information from people that had the same problems as you did.
Hope it helps!

Resources