Apache C module creation, problem linking SQLite - c

Playing around with this a bit, but not getting too far...
The logic of my SQLite code works if I compile it as a stand-alone executable.
My mod_hello.c compiles and loads/works fine without the SQLite code
Combining the two, the module compiles and is installed, but the apache process dies immediately every time it is loaded. Stripping out all the SQLite code and simply linking against SQLite causes this problem. In other words, with the same code:
apxs -cia -L/usr/local/lib -I/home/devin mod_hello.c
/* Works Fine, prints "hello world" */
apxs -cia -L/usr/local/lib -I/home/devin -lsqlite3 mod_hello.c
/* compiles but dies on apache load */
The platform is OpenBSD 4.6 with the platform's version of Apache 1.3 and SQLite 3.6.20 downloaded from the SQLite site and compiled from source

The problem had to do with my downloading SQLite and compiling - when I deleted all those resulting files and installed the OpenBSD package for SQLite, it worked fine. So there must be some platform-specific compile tweaks needed for the SQLite library. Best to use the packages I guess.
-- devin

Normally when this happens, either libsqlite3.so isn't in LD_ LIBRARY_PATH, or libsqlite3.so isn't quite what you want to link to, i.e. there's e.g. libsqlite3.1.so that you want to link to. So my advice is to check the load-time paths, to make sure libsqlite3.so is there, and to check if there's a libsqlite3.x.so somewhere that you may need to link to instead. (-lsqlite3.x instead of -lsqlite3

Related

How to make linked readline library relocatable in Cmake

Firstly, I am not sure if the title exactly words my question well but after three days of searching the web and SO for no working answer, please bear with me.
So the problem is that I have a C application where CMake is the build system. This application relies on libreadline and I can correctly find and link with it using the snippet below:
find_library(READLINE_LIBRARY readline REQUIRED)
target_link_libraries(myExe PRIVATE "${READLINE_LIBRARY}")
The problem is that when I build the application on a system with say for example libreadline.so.8 which is the version 8 and move the application to another system that only has libreadline.so.7 or none available, I'll have to install the missing library before I can run the application. This make for a very bad user experience.
I have tried setting the #rpath before the add_executable and add_library with:
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:$ORIGIN")
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
The problem is that while that correctly sets the #rpath for a shared library which forms part of the project, it doesn't do the same for libreadline. Also even if for any reason I am able to get it to work, I don't know how to get call to find_library return a relocatable library (meaning I can't bet that the libreadline.so.8 was build with -fPIC or not).
Whatever I do, I can't get a local copy of libreadline in my build output directory.
Also note that this problem exists on OSX as well just using the Linux example for simplicity.
On OSX when I inspected the executable with tool -l myExe, I noticed that only the Load Command section for the shared executable which is part of my project correctly uses #rpath while the editline (OSX deadline seems to just be an editline) looks like this:
Load command 14
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libedit.3.dylib (offset 24)
Any help will be appreciated. I'm quite stuck. But one thing I'm certain of it that I have seen applications that does this which means it's very possible.

gtk.h missing in Visual Studio for Linux Development

I'm currently trying to write an app for Raspberry Pi 3B under Rasbpian with aid of Linux Development plugin in Visual Studio 2017 Community. I managed to successfully deploy 'Blink' example, nobly attached by Microsoft folks, according to tutorial, and that went well. I even made some transmission over SPI thanks to wiringPi library. Then I would like to add some GUI to my app, so that one could, for example, make some transmission on click of a button on screen.
IntelliSense hinted me, that, in fact, there is gtk-3.0 library present in toolset. It seems that libraries are being copied from target device on every connection or so and I installed gtk on my Raspberry. So I added a simple line to this Blink example:
#include <gtk-3.0/gtk/gtk.h>
On compilation attempt, of course there was nearly 4k errors. Well, enough said, with a little hint from this old tutorial and a bit of trial and error, I managed to add this set of links under Debugging/Project properties/Configuration properties/VC++ directories/Header files directories:
Everything goes in promising direction, as errors number diminished from 4k to just one:
gtk-3.0\gtk\gtk.h: No such file or directory
No matter that this file is ACTUALLY in this location:
Regardless of combination of links in configuration above and using statement composition, compiler (?) can't find this damn file.
Please Halp
EDIT
I just confirmed, that it is indeed problem with target configuration. This is bad or good, depending on point of view. Good, because there is probably all good with VS setup. Bad, because I don't know a thing about compiling things under Linux.
On target (Raspberry Pi 3B) all ingredients for compilation are copied by Linux Development plugin. So in Terminal I executed line:
g++ main.cpp -o Blink2onRPi
and got
main.cpp:4:21: fatal error: gtk/gtk.h: no such file or directory
Now, I altered include line in main.cpp on target RPi, to this:
#include <gtk-3.0/gtk/gtk.h>
And now its missing <gdk/gdk.h>! When this change is made on host windows device - same result, but in VS.
As I dealt with similar problem in VS, upon setting links for IntelliSense (now apparently they're for this purpose), now probably similar dependencies have to be set somewhere on Raspbian. But where?
EDIT2
Upon execution of:
g++ main.cpp -o Blink2onRPi `pkg-config --cflags --libs gtk+-3.0`
on target RPi there is no more GTK-related errors, just wiringPi (also present in project) undefined references. It raises two possible questions:
1) How can I setup wiringPi on RPi so that the project could be manually compiled on target and
2) How/where add above line to Visual Studio, so it execute remotely with all GTK dependencies added properly on target
Researching stock present wiringPi library (as this is Blink led example for cross-compile Linux Development) I've found, that in Project Properties/Linker/Input/Library Dependencies there is mysterious entry:
wiringPi
Just that, nothing more. After removing this entry, on compilation pops out same errors as before on target (which apparently lacks proper wiringPi setup) - undefined references (not mensioned any missing headers). Can this be relevant for the case? If so, how could I add there such entry which would deal with missing GTK dependencies?
TL;DR
Use screenshot below to know where to add pkg-config calls in VS configuration so that it forwards it to the compiler and linker on the target.
Thanks to #zaguoba for providing these.
ORIGINAL ANSWER:
The list of directories to include is provided by pkg-config. For example pkg-config --cflags-only-I gtk+-3.0 will give you the list of include directories required. Those are the ones you need to add to the directories where VC++ wil look at include files. If you add the relative path you use in the #include, to one of those paths, you are able to find the file.
Example:
If you add to the directories C:\Program Files\foo\bar\gtk+-3.0
and have in your C file:
#include <gtk/gtk.h>
then the compiler will look for C:\Program Files\foo\bar\gtk+-3.0\gtk\gtk.h.
EDIT:
This all means the 'file not found' errors are because you're really building on the target and the target has no idea what C:\Program Files\... means. Those should be paths on the target filesystem, where the compiler is called. And this is exactly what pkg-config provides.
The copy of those files on the Windows machine filesystems is merely for Intellisense use, not for compiler use.
EDIT 2:
So that's that Visual Studio 2017 Community Linux Development plugin is what need to be undestood. It's not for cross compilation from Windows to Linux, istead it merely synchronizes code to the Windows host (for Intellisense use), but builds on the target. This means that all the paths and commands are Linux paths and commands, run on the target.
Here's the OP working configuration:
With that setup, you should
#include <gtk\gtk.h>
instead of
#include <gtk-3.0\gtk\gtk.h>
Alternatively remove all those VC++ directories/Header files directories, and just keep one of them that ends with include/ instead of listing up all the sub directiores.

Missing libgcc_s_dw2-1.dll

I have a Windows 7 64bit system with the latest MinGW (32bit) installed along with the Qt 5.5 SDK (again 32bit) which also ships with its own MinGW. Due to the fact that I'm not the only one using the system I can't remove the standalone MinGW.
My project is using qmake and is a plain C project (not C++). Everything builds fine but when I try to execute my binary in the command line I get that the application was unable to start due to a missing libgcc_s_dw2-1.dll on the system.
After looking into the issue I found that both the standalone MinGW and the one shipped alongside the Qt SDK have the mentioned DLL.
Standalone MinGW - libgcc_s_dw2-1.dll is located inside the bin subdirectory of the MinGW installation where the binaries are located (gcc, g++, gdb etc.)
Qt MinGW - libgcc_s_dw2-1.dll is located inside C:\Qt\Tools\mingw492_32\i686-w64-mingw32\lib subdirectory while the MinGW components' binaries are inside C:\Qt\Tools\mingw492_32\i686-w64-mingw32\bin.
I would like to know how to properly set my PATH variable so that:
The application starts properly
No conflicts with the standalone MinGW installation occur
Just a side-note: I've already checked other posts here on SO but was unable to find a solution (perhaps I've missed it). I have also tried LIBS += -static but the result is the same.
You just need to copy this dll with your executable, i.e.:
cp <path-to-qt-install-dir>\qt5.7.0\5.7\mingw53_32\bin\libgcc_s_dw2-1.dll <path-to-dest-dir>
You mat find that you have other dependencies, to see which other deps you have you can use: ldd <your-executable>. You only need to copy the qt specific dlls you can see these by:
ldd <executable> | grep -i qt
note
You can statically link it with:
linker commands like -static-libgcc or -static, but I think you start to hit LGPL issues and also you may need to statically compile qt from source - can't recall for this particular file.
note2
Sorry ldd is for linux, just realized you have windows, in which case you can use one or both of:
dependency walker: from here
<path-to-qt-bin-folder>\windeployqt.exe <path-to-your-executable>
I have mixed results with windeployqt, but if you have any plugins its quiet good for getting that part sorted.

How to created a shared library (dylib) using automake that JNI/JNA can use?

How do I convince LibTools to generate a library identical to what gcc does automatically?
This works if I do things explicitly:
gcc -o libclique.dylib -shared disc.c phylip.c Slist.c clique.c
cp libclique.dylib [JavaTestDir]/libclique.dylib
But if I do:
Makefile libclique.la (which is what automake generates)
cp .libs/libclique.1.dylib [JavaTestDir]/libclique.dylib
Java finds the library but can't find the entry point.
I read the "How to create a shared library (.so) in an automake script?" thread and it helped a lot. I got the dylib created with a -shared flag (according to the generated Makefile). But when I try to use it from Java Native Access I get a "symbol not found" error.
Looking at the libclique.la that is generated by Makefile it doesn't seem to have any critical information in it, just looks to be link overloads and moving things around for the convenience of subsequent C/C++ compiler steps (which I don't have), so I would expect libclique.1.dylib to be a functioning dynamic library.
I'm guessing that is where I'm going wrong, but, given that JNA links directly to a dylib and is not compiled with it (per the example in the discussion cited above), it seems all the subsequent compilation steps described in the LibTools manual are moot.
Note: I'm testing on a Mac, but I'm going to have to do this on Windows and Linux machines also, which is why I'm trying to put this into Automake.
Note2: I'm using Eclipse for my Java development and, yes, I did import the dylib.
Thanks
You should be building a plugin and in particular pass
libclique_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
This way you tell libtool you want a dynamically loadable module rather than a shared library (which for ELF are the same thing, but for Mach-O are not.)

Linking a static library to an Apache module

I am experimenting with Apache module development and therefore I'd like to know how to link a static library to a module (if it is even possible).
Naturally it compiles and installs nicely and Apache fails when the module is loaded. The message is:
Cannot load /usr/lib/apache2/modules/mod_example.so into server: /usr/lib/apache2/modules/mod_example.so: undefined symbol: zmq_socket
The library I want to link is zeromq, I am using the makefile generated by apxs2. Here I added -lzmq. If I remove zmq related code, the module runs fine.
My platform is Ubuntu 12.04 64 bit, gcc4.6.3.
well, apparently the generated makefile is not a good idea. I replaced the makefile references with basic compilation commands, e.g.:
apxs2 -c -lzmq mod_example.c
alk's suggestion in the comment of the question would also work (adding library location to LD_LIBRARY_PATH), since I was linking another apache-related library (apreq), which linked without any problems.

Resources