I created a custom module for Apache2.4 that uses an external library (MagickWand). I installed it using sudo apt-get install libmagickwand-dev, but now, what I have to do in order to use it with Apache2.4? When I restart the apache2 service I got the undefined symbol error about a function on MagickWand.
I read that I should load the shared object of the library, but how can I create it? Using apxs? Where?
Thank you very much in advance!
there are two config files in apache2 that you will need to modify:
(for linux)
in the /etc/apache2 there are sub directories of interest:
./mods-available and ./mods-enabled and ./conf-available and ./conf-enabled
The ./mods-available directory contains ALL the loadable modules, all with the .load extension on their file name
The ./mods-enabled directory contains links to the loadable modules in the ./mods-available directory that are to be loaded and links to the .conf file for each of the .conf files (for the individual loadable modules) that are actually to be loaded.
the ./conf-available directory contains all the .conf files for the loadable modules
The ./conf-enabled directory contains links to the files in the ./conf-available directory for the loadable modules configurations that will be actually used
Then in the /etc/apache2 directory is the file apache2.conf that can contain (amongst other things) these two statements:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
This is what directs apache2 to actually load modules and their related conf files
The following response is to help others:
In order to compile a custom apache module using apxs with MagickWand library, first include the header file wand/magick-wand.h in your C file. Let's say it is mod_example.c:
So, in mod_example.c add:
#include "wand/magick-wand.h"
Now, when compiling the module using apxs include the directories which MagickWand will require during the build process using -I flag and mention the library name using -l flag
sudo apxs -c -i -I/usr/include/ImageMagick-6 -I/usr/include/x86_64-linux-gnu/ImageMagick-6 -lMagickWand-6.Q16 /path/to/mod_example.c
Please note, your library version may be different.
Related
I'm working on a buildroot-based linux for my actual project. I need to add the protobuf-c library and found that the library files, .a and .la, dissapear from the target directory after the "Finalizing target" step in buildroot, since it executes a command to arase all .a and .la files from target/usr/lib and target/lib, so they are empty on the target. Obviously after loading on the target files are still missing.
Can anyone help me on how I can find those files or how can I fix this?
I've tried installing other libraries from the buildroot menuconfig and the same happens, files are installd in /usr/lib directory, but at the end after the "Finalizing target" step they dissapear.
Thanks in advance
Buildroot will typically strip and install the shared libraries which end in .so
The static library ending in .a can be installed by implementing a post install hook in your package makefile. This hook looks like the following for an example package called "pack". In this case the following would be put into the pack.mk makefile :
define PACK_INSTALL_MOD
$(INSTALL) -D -m 755 $(#D)/.libs/libpack.a $(TARGET_DIR)/usr/lib/
endef
PACK_POST_INSTALL_TARGET_HOOKS += PACK_INSTALL_MOD
Previously, I'm looking for this kind of question but none of them are working as example this thread and this one.
Currently, I'm creating a C library which supposed to outputs a shared library (*.so or *.dll) file and multiple *.h files in a ./include directory. The shared library is successfully built and installed to /usr/local/lib. However, I have no idea how do I tell CMake to copy *.h files to the correct destination as below.
In POSIX: /usr/local/include
In Windows: C:\<Compiler Path>\include
I know I could workaround this by copying those *.h with Python script or using if-else logic on CMake. But at least tell me if there is a feature in CMake for doing that thing. Thanks!
Here's my CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project (
learn_c_library
VERSION 1.0.0
LANGUAGES C
)
# Specify CMake build and output directory
set(CMAKE_BINARY_DIR "${PROJECT_SOURCE_DIR}/.cmake")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/out")
# Use every .c file inside ./src
file(GLOB_RECURSE MY_SOURCE_PATH "src/*")
add_library(
${PROJECT_NAME} SHARED
${MY_SOURCE_PATH}
)
include_directories(
${PROJECT_NAME}
"include/"
)
# Allows "make install" to install shared library
install(TARGETS ${PROJECT_NAME})
This answer improves on your answer:
cmake_minimum_required(VERSION 3.14)
# ...
include(GNUInstallDirs)
install(DIRECTORY "include/"
TYPE INCLUDE
COMPONENT MyProj_Development)
The GNUInstallDirs module provides standard configuration points for customizing a project's install layout. These variables should essentially always be used instead of hardcoding path/directory names.
The TYPE INCLUDE argument to install() was introduced in CMake 3.14 and uses GNUInstallDirs's CMAKE_INSTALL_INCLUDEDIR variable to determine the destination.
Finally, and especially if your project is a library, all your install() rules should be given a COMPONENT argument to allow splitting files between runtime and development packages (and potentially others like documentation and architecture-independent data files).
After days of fiddling CMake, finally I found the solution!
Let's assume you store your public *.h inside ./include directory, then here's the syntax for installing your *.h files to your machine:
install(
DIRECTORY
"include/" # Your global headers location in the project
DESTINATION
include # This is your system's default "include" location
)
I got the solution from here with usr/myproject replaced to be include
I am building locally a dependencies and installing in a local directory. Now I would like to tell CMake to look into that local directory for include and libraries, in addition to all the standard places.
I tried this:
cmake -D CMAKE_LIBRARY_PATH=`realpath ../target`/lib CMAKE_INCLUDE_PATH=`realpath ../target`/include .
But it did not work. Any idea?
You can use the
find_library()
command to search for libraries.
With
include_directories()
you tell cmake where to look for include files
You can first add the folder to your PC's system environment, e.g. called PersonalLib_DIR that points to the folder. Then you can add it for include and libraries by accessing $ENV{PersonalLib_DIR} via CMake:
For include:
include_directories($ENV{PersonalLib_DIR})
For libraries (assume you want to link the aLib.lib under the folder):
target_link_libraries(youProject $ENV{PersonalLib_DIR}/aLib)
I've built nginx on my target machine (Linux) with a 3rd party module (ngx_mongo).
This module required two additional libraries to be present: pcre and yajl.
I built and installed these two separately and they installed to /usr/local/lib and headers to /usr/local/include.
I then configured nginx's build: configure --add-module=/home/greg.zoller/working/ngx_mongo
This found all the needed libs and successfully built w/o errors.
Installed nginx to default /usr/local/nginx.
When I go to run /usr/local/nginx/sbin/nginx I get this error:
./nginx: error while loading shared libraries: libyajl.so.2: cannot open shared object file: No such file or directory
Why can't it find libyajl.so.2? This file exists in /usr/local/lib and the build found it.
I ran ldconfig -v and the yajl library was not there. I tried running (as root and not) just ldconfig. No change.
What am I missing?
The dynamic loader only looks for libs present in folders declared in /etc/ld.so.conf. /usr/local/lib may not be there by default. Also when a new lib is added, you need to run ldconfig since the contents of lib folders are cached.
I've done this before a couple of times, but somehow I'm stuck this time. I have an executable "myapp" and a own shared library "mylib". In my cmakelists I have the following:
ADD_LIBRARY(mylib SHARED ${SOURCES_LIB})
INSTALL(TARGETS mylib DESTINATION .)
ADD_EXECUTABLE(myapp ${SOURCES_APP})
TARGET_LINK_LIBRARIES(myapp ${QT_LIBRARIES} mylib)
INSTALL(TARGETS myapp DESTINATION .)
Everything compiles and links correctly, but when I start myapp, I get the following error:
error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory
The lib and the executable are present in the install directory. When I make my library static by changing the first line of the above cmakelists to:
ADD_LIBRARY(mylib STATIC ${SOURCES_LIB})
then everything works 100%.
Does anyone know what I'm doing wrong?
During the installation of your library and executable, the runtime paths to find the library are stripped from the executable. Therefore your library has to reside in the runtime library search path. For example under Linux, try to set LD_LIBRARY_PATH to the directory that contains the installed library when starting your executable.
This is a very common question about "make install". Actually, there are 3 ways to link a library to your executable file. First, you may use -l -L flags in simple cases. As Benjamin said you may use LD_LIRARY_PATH and write something like: export LD_LIBRARY_PATH=/usr/local/my_lib. In fact this is not a good way. It's much better to use RPATH. There is a very useful doc page about it. Check it out. Well if you write something like this in your top level CMakeLists.txt, it will solve the problem:
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib64")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib64")
Add the path of the directory containing the library to the LD_LIBRARY_PATH environment variable, by appanding a new path:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/the/library/
You can check the library is correctly found with the 'ldd' tool:
lld ./executable
If the library is not stated as "not found" it is OK and your executable will be executed properly.
Add the 'export' command to your bashrc to properly set the LD_LIBRARY_PATH variable after each system reboot, otherwise you will have to execute again the 'export' command.