Create symlink to /usr/local/lib/cmake from Homebrew Formula - ruby

I wrote a custom Homebrew Formula to distribute some library. I'm happy with the result, but there's an outstanding problem. I would like to install the cmake config file (YORPLibConfig.cmake) in /use/local/lib/cmake.
Unfortunately, this location appears to be out of reach from within the Formula. I had no problems to install the library and its headers thanks to the nifty lib.install and include.install functions, but I'm out of luck since there's no lib/cmake.install equivalent.
I also tried to manually create the symlink by doing
ln_sf "YORPLibConfig.cmake", "/usr/local/lib/cmake/"
but the install fails upon throwing
Error: Operation not permitted # rb_file_s_symlink - (YORPLibConfig.cmake, /usr/local/lib/cmake/YORPLibConfig.cmake)
How can I install this cmake file in /usr/local/lib/cmake from within the Formula?
The formula itself:
class Yorplib < Formula
desc "A library for the computation of the Fourier decomposition of YORP forces and moments"
homepage "https://github.com/bbercovici/YORPLib"
url "https://github.com/bbercovici/YORPLib/archive/1.0.0.tar.gz"
sha256 "45fb9a2969368e76e472a39afa8feb32c27cbe17032371e06fd283f3d70bb7c7"
depends_on "cmake" => :build
def install
# Compile
system "cmake . -DBREW:BOOL=TRUE && make"
prefix.install "YORPLibConfig.cmake"
# Create symlink to library
ln_sf "YORPLibConfig.cmake", "/usr/local/lib/cmake/"
lib.install "libYORPLib.dylib"
include.install "include/"
end
end

I ended up modifying both the formula and the CMakeLists.txt file so as to install a symlink to the configuration file in /usr/local/share. The configuration file pointed at by the symlink resides in the Cellar.

Related

Why can this dynamic library file include all dependencies? [duplicate]

Program is part of the Xenomai test suite, cross-compiled from Linux PC into Linux+Xenomai ARM toolchain.
# echo $LD_LIBRARY_PATH
/lib
# ls /lib
ld-2.3.3.so libdl-2.3.3.so libpthread-0.10.so
ld-linux.so.2 libdl.so.2 libpthread.so.0
libc-2.3.3.so libgcc_s.so libpthread_rt.so
libc.so.6 libgcc_s.so.1 libstdc++.so.6
libcrypt-2.3.3.so libm-2.3.3.so libstdc++.so.6.0.9
libcrypt.so.1 libm.so.6
# ./clocktest
./clocktest: error while loading shared libraries: libpthread_rt.so.1: cannot open shared object file: No such file or directory
Is the .1 at the end part of the filename? What does that mean anyway?
Your library is a dynamic library.
You need to tell the operating system where it can locate it at runtime.
To do so,
we will need to do those easy steps:
Find where the library is placed if you don't know it.
sudo find / -name the_name_of_the_file.so
Check for the existence of the dynamic library path environment variable(LD_LIBRARY_PATH)
echo $LD_LIBRARY_PATH
If there is nothing to be displayed, add a default path value (or not if you wish to)
LD_LIBRARY_PATH=/usr/local/lib
We add the desired path, export it and try the application.
Note that the path should be the directory where the path.so.something is. So if path.so.something is in /my_library/path.so.something, it should be:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/my_library/
export LD_LIBRARY_PATH
./my_app
Reference to source
Here are a few solutions you can try:
ldconfig
As AbiusX pointed out: If you have just now installed the library, you may simply need to run ldconfig.
sudo ldconfig
ldconfig creates the necessary links and cache to the most recent
shared libraries found in the directories specified on the command
line, in the file /etc/ld.so.conf, and in the trusted directories
(/lib and /usr/lib).
Usually your package manager will take care of this when you install a new library, but not always, and it won't hurt to run ldconfig even if that is not your issue.
Dev package or wrong version
If that doesn't work, I would also check out Paul's suggestion and look for a "-dev" version of the library. Many libraries are split into dev and non-dev packages. You can use this command to look for it:
apt-cache search <libraryname>
This can also help if you simply have the wrong version of the library installed. Some libraries are published in different versions simultaneously, for example, Python.
Library location
If you are sure that the right package is installed, and ldconfig didn't find it, it may just be in a nonstandard directory. By default, ldconfig looks in /lib, /usr/lib, and directories listed in /etc/ld.so.conf and $LD_LIBRARY_PATH. If your library is somewhere else, you can either add the directory on its own line in /etc/ld.so.conf, append the library's path to $LD_LIBRARY_PATH, or move the library into /usr/lib. Then run ldconfig.
To find out where the library is, try this:
sudo find / -iname *libraryname*.so*
(Replace libraryname with the name of your library)
If you go the $LD_LIBRARY_PATH route, you'll want to put that into your ~/.bashrc file so it will run every time you log in:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/library
Update
While what I write below is true as a general answer about shared libraries, I think the most frequent cause of these sorts of message is because you've installed a package, but not installed the -dev version of that package.
Well, it's not lying - there is no libpthread_rt.so.1 in that listing. You probably need to re-configure and re-build it so that it depends on the library you have, or install whatever provides libpthread_rt.so.1.
Generally, the numbers after the .so are version numbers, and you'll often find that they are symlinks to each other, so if you have version 1.1 of libfoo.so, you'll have a real file libfoo.so.1.0, and symlinks foo.so and foo.so.1 pointing to the libfoo.so.1.0. And if you install version 1.1 without removing the other one, you'll have a libfoo.so.1.1, and libfoo.so.1 and libfoo.so will now point to the new one, but any code that requires that exact version can use the libfoo.so.1.0 file. Code that just relies on the version 1 API, but doesn't care if it's 1.0 or 1.1 will specify libfoo.so.1. As orip pointed out in the comments, this is explained well at here.
In your case, you might get away with symlinking libpthread_rt.so.1 to libpthread_rt.so. No guarantees that it won't break your code and eat your TV dinners, though.
You need to ensure that you specify the library path during
linking when you compile your .c file:
gcc -I/usr/local/include xxx.c -o xxx -L/usr/local/lib -Wl,-R/usr/local/lib
The -Wl,-R part tells the resulting binary to also look for the library
in /usr/local/lib at runtime before trying to use the one in /usr/lib/.
Try adding LD_LIBRARY_PATH, which indicates search paths, to your ~/.bashrc file
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path_to_your_library
It works!
The linux.org reference page explains the mechanics, but doesn't explain any of the motivation behind it :-(
For that, see Sun Linker and Libraries Guide
In addition, note that "external versioning" is largely obsolete on Linux, because symbol versioning (a GNU extension) allows you to have multiple incompatible versions of the same function to be present in a single library. This extension allowed glibc to have the same external version: libc.so.6 for the last 10 years.
cd /home/<user_name>/
sudo vi .bash_profile
add these lines at the end
LD_LIBRARY_PATH=/usr/local/lib:<any other paths you want>
export LD_LIBRARY_PATH
Another possible solution depending on your situation.
If you know that libpthread_rt.so.1 is the same as libpthread_rt.so then you can create a symlink by:
ln -s /lib/libpthread_rt.so /lib/libpthread_rt.so.1
Then ls -l /lib should now show the symlink and what it points to.
I had a similar error and it didn't fix with giving LD_LIBRARY_PATH in ~/.bashrc .
What solved my issue is by adding .conf file and loading it.
Go to terminal an be in su.
gedit /etc/ld.so.conf.d/myapp.conf
Add your library path in this file and save.(eg: /usr/local/lib).
You must run the following command to activate path:
ldconfig
Verify Your New Library Path:
ldconfig -v | less
If this shows your library files, then you are good to go.
running:
sudo ldconfig
was enough to fix my issue.
I had this error when running my application with Eclipse CDT on Linux x86.
To fix this:
In Eclipse:
Run as -> Run configurations -> Environment
Set the path
LD_LIBRARY_PATH=/my_lib_directory_path
Wanted to add, if your libraries are in a non standard path, run ldconfig followed by the path.
For instance I had to run:
sudo ldconfig /opt/intel/oneapi/mkl/2021.2.0/lib/intel64
to make R compile against Intel MKL
All I had to do was run:
sudo apt-get install libfontconfig1
I was in the folder located at /usr/lib/x86_64-linux-gnu and it worked perfectly.
Try to install lib32z1:
sudo apt-get install lib32z1
If you are running your application on Microsoft Windows, the path to dynamic libraries (.dll) need to be defined in the PATH environment variable.
If you are running your application on UNIX, the path to your dynamic libraries (.so) need to be defined in the LD_LIBRARY_PATH environment variable.
The error occurs as the system cannot refer to the library file mentioned. Take the following steps:
Running locate libpthread_rt.so.1 will list the path of all the files with that name. Let's suppose a path is /home/user/loc.
Copy the path and run cd home/USERNAME. Replace USERNAME with the name of the current active user with which you want to run the file.
Run vi .bash_profile and at the end of the LD_LIBRARY_PATH parameter, just before ., add the line /lib://home/usr/loc:.. Save the file.
Close terminal and restart the application. It should run.
I got this error and I think its the same reason of yours
error while loading shared libraries: libnw.so: cannot open shared
object file: No such file or directory
Try this. Fix permissions on files:
cd /opt/Popcorn (or wherever it is)
chmod -R 555 * (755 if not ok)
I use Ubuntu 18.04
Installing the corresponding -dev package worked for me,
sudo apt install libgconf2-dev
Before installing the above package, I was getting the below error:
turtl: error while loading shared libraries: libgconf-2.so.4: cannot open shared object file: No such file or directory
I got this error and I think its the same reason of yours
error while loading shared libraries: libnw.so: cannot open shared object
file: No such file or directory
Try this. Fix permissions on files:
sudo su
cd /opt/Popcorn (or wherever it is)
chmod -R 555 * (755 if not ok)
chown -R root:root *
A similar problem can be found here.
I've tried the mentioned solution and it actually works.
The solutions in the previous questions may work. But the following is an easy way to fix it.
It works by reinstalling the package libwbclient
in fedora:
dnf reinstall libwbclient
You can read about libraries here:
https://domiyanyue.medium.com/c-development-tutorial-4-static-and-dynamic-libraries-7b537656163e

homebrew locate installed files path

I have a homebrew package that I was able to push through GitHub: diagnosticator
This is a simple ruby file (diagnosticator.rb) that points to the actual hosting repository: diagnosticator-mac and provides instructions on how to install files:
class Diagnosticator < Formula
desc "Diagnosticator Mac OS homebrew package"
homepage "https://diagnosticator.com"
url "https://github.com/cccnrc/diagnosticator-mac/archive/refs/tags/v0.1.11.tar.gz"
sha256 "f36987ce96c7be269da12b9dce8186c5245aef4046fe62173a145024b5e88b98"
license "MIT"
depends_on "docker"
depends_on "docker-compose"
depends_on "wget"
depends_on "jq"
def install
bin.install "diagnosticator"
bin.install "diagnosticator-mac.sh"
bin.install Dir["files"]
prefix.install "README.md"
end
end
From the diagnosticator executable I have to refer to diagnosticator-mac.sh executable, I am now referring it as:
MAC_EXE=/usr/local/bin/diagnosticator-mac.sh
but I guess I can simply change it to:
MAC_EXE=diagnosticator-mac.sh
as it will be found on the $PATH after installation.
From diagnosticator-mac.sh I have to refer to files in the files folder that are installed through bin.install Dir["files"], I have now:
DIAGNOSTICATOR_FILES_DIR=/usr/local/opt/diagnosticator/bin/files
but I noticed that in a couple of different Mac machines they ended up in different locations based on how users installed homebrew.
How can I find a way to point the diagnosticator-mac.sh executable to that files folder however homebrew was installed?
If you want to try it:
brew install cccnrc/diagnosticator/diagnosticator
Homebrew determines the path for you, and stores it in the variable HOMEBREW_PREFIX
You could use inreplace to swap your hardcoded prefix with the homebrew prefix.
# Iterate through the files, replacing the prefix
%w[diagnosticator diagnosticator-mac.sh].each do |file|
inreplace file, "/usr/local", HOMEBREW_PREFIX
end

Set executable permission on script installed with Homebrew

I wrote my first tap, so I'm still not sure how it works. I wrote this small formula:
class Konversation < Formula
desc "Konversation is a tool to generate rich and diversified responses to the user of a voice application."
homepage "https://github.com/rewe-digital-incubator/Konversation/"
url "https://github.com/rewe-digital-incubator/Konversation/releases/download/1.0.0/konversation-cli.jar"
sha256 "6123d126278faae2419f5de00411a1b67ae57e0cf2265a5d484ed6f9786baaca"
def install
prefix.install "#{buildpath}/konversation-cli.jar"
File.write("#{buildpath}/konversation", "java -jar #{prefix}/konversation-cli.jar $#")
bin.install "#{buildpath}/konversation"
system "chmod", "+x", "#{bin}/konversation"
end
end
However I cannot run my tool since the "konversation" executable has no x permission. I tried to fix that with a system chmod, however I see that my x flag is removed after the installation by brew as some kind of cleanup:
==> Cleaning
Fixing /home/linuxbrew/.linuxbrew/opt/konversation/bin/konversation permissions from 777 to 444
How can I set the file permissions correctly?
Please note that I don't want to host the shell script itself somewhere, since I see no advance in packaging the shell script and the jar file in another zip file for destitution.
If you want to try it yourself try this command:
brew install rekire/packages/konversation
Shell scripts need to have a shebang line, otherwise the postinstall cleaner will set its permissions as though it were not an executable. In this specific case, I suggest:
use bin.write_jar_script instead -- this will set up the correct environment for JAR scripts
install .jars to libexec instead of prefix -- to avoid polluting the prefix with unnecessary files.
Example formula from Homebrew/homebrew-core

Missing dynamic (.so) library in fftw 2.1.5 installation

I am trying to run simulations using Gadget2, an astrophysics N-body simulation package. It requires a few libraries, including fftw-2.1.5. I have installed fftw using the guidelines given in the user manual:
./configure --prefix=<PATH> --enable-typeprefix --enable-mpi
make
make install
make clean
./configure --prefix=<PATH> --enable-float--enable-type-prefix --enable-mpi
make
make install
The two makes are to get both single and double precision files according to this source. The install happened successfully, and I was also able to compile Gadget2.
But when I try to run Gadget2, I get the following error:
./Gadget2: error while loading shared libraries: libsrfftw_mpi.so.2: cannot open shared object file: No such file or directory
The file libsrfftw_mpi.so.2 is missing in the fftw lib folder, even though a few download sites for fftw packages say that it is part of the contents. What am I missing?
Specify the below and run your command again.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH=<PATH from your install command>
also don't forget to additionally specify --enable-shared for both configure commands.

Trouble installing OpenCV with Cmake

I am trying to install the openCV library for Python however I am new to CMake and have run into some trouble after having cloned the repository in ~/opencv.
I've made a build directory in it with the mkdir command however once inside it when trying to set CMake options in it.
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local
I get prompted with the following error:
CMake Error: The source directory "/Users/eDen/opencv/build/CMAKE_INSTALL_PREFIX=/usr/local" does not exist.
It seems you aren't making the right directory, some Mac OS X installations doesn't include /usr/local/. You can make the directory using, if it's not already created, with:
sudo mkdir /usr/local/
But you say you want to use OpenCV with Python. I recommend you to obtain an already compiled copy unless you need some advanced features not available in the compiled version, like Qt integration or CUDA programming. But these features are included in the arguments of the cmake command.
Instructions on how to obtain OpenCV from Homebrew repository, this page explains the process. Basically, you install Homebrew, then Python, configure it and install some dependencies.
As Tsyvarev mentioned in the comments, you need to specify the path to source directory (i.e. where the main CMakeLists.txt file exists) at the end of your command. So, supposing you are now in the build directory, the final cmake command would be as follows:
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
I have the last argument as .. but still get the error.
In my case, there is a bad whitespace in the above arguments. So the last .. is ignored.

Resources