How to make Cmake globally available - linux

I just installed Cmake from git clone wget http://www.cmake.org/files/v2.8/cmake-2.8.3.tar.gz in a new folder on a Linux server. The compilation worked but cmake command is not recognized from other paths. Should I copy the entire contents of cmake-2.8.0 folder to usr/local/bin? Or is the contents of bin folder that need to be copied?
Thanks

On Linux and other Unix-based systems, a common arrangement is to install packages to /opt and add relevant entries to the PATH environment variable to make them available. This is intended for packages not provided by the native package manager or distribution. By choosing an appropriate directory structure, this can be done in a way which also allows different versions to be installed simultaneously and the user can pick which one they want by adding the relevant directory to the PATH.
For the specific case of CMake asked about in the question, you can use a directory structure like /opt/cmake/<version> and then add the relevant /opt/cmake/<version>/bin directory to your PATH (e.g. /opt/cmake/3.8.2/bin for the 3.8.2 CMake release). You can even just download the official pre-built CMake tarballs, unpack them and move the top level directory into the /opt/cmake area as the particular version you downloaded. I've used this successfully on Linux, MacOS and Solaris, as I'm sure have many others.
Note that once you've run CMake on a particular source tree, the cmake executable doesn't need to be on the PATH any more. If cmake needs to be re-run, the build will do so itself and it records the full path to the cmake executable in its own cache, so the PATH isn't even consulted (this is essential in ensuring the same version of CMake continues to be used for all builds regardless of the PATH, since PATH can change between login sessions, etc.). You would only need cmake on your PATH if you intend to invoke cmake manually or for the first time you run it on a source tree, but in both of these cases you can always just use the full path to the cmake executable if you preferred.
I should also add that the entire set of files provided in the CMake package are required, not just the bin directory. CMake makes extensive use of files in its other directories, such as the various modules it comes with. If you are building CMake from source, you may want to build the package target so you get a relocatable tarball or similar which will contain everything that should be included when you provide a CMake package on your system.

After the build, use 'sudo make install'. This will make sure the correct libraries and binaries are copied to their proper places.
Usually this will install the binary to /usr/local/bin.
Make sure the PATH variable has this included.

sudo make install did not copy to /usr/local/bin/ for some reason, so I copied the content of CMAKE /bin. to usr/local/bin an it worked.
cp –a bin/. /usr/local/bin/

Related

Removing source code directory after compiling libraries

I have downloaded the source code from git for some third-party libraries, which contains a makefile, and so I have run make to compile the libraries. During compilation, this seems to add various libraries to directories such as /usr/bin. My questions is: now that I have compiled the code and the libraries have been written to other locations on my machine, can I delete the original folder with the source code in? Or will I still need this to run these libraries?
Generally, a source code installation need 3 steps: ./configure; make; make install
make install will copy the compiled out binaries and libraries to target system directories. After that, removing the source code folder will not impact the binaries and libraries execution since they have been deployed on your system.

Can I avoid exporting LD_LIBRARY_PATH by hardcoding library paths in the executable?

I'm zipping a pre-built (no source/object files) binary application for distribution. The binary application requires a couple of libraries not included by default. The only way I seem to be able to get the application to start on the end-user is by including a run.sh that sets the library path to the current directory:
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
./MyApp.out
However, I'd really like to allow the user to just unzip the zip and doubleclick MyApp.out (without the shell script). Can I edit MyApp.out to search the current directory for the library? I've done something similar on OSX using install_name_tool, but that tool isn't available here.
You want to set the rpath. See this answer. So link using
gcc yourobjects*.o -L/some/lib/dir/ -lsome -Wl,-rpath,.
But you might want even to use -Wl,-rpath,$PWD or perhaps -Wl,-rpath,'$ORIGIN'. See this.
You could also (and this should work for a pre-built executable) configure your /etc/ld.so.conf by adding a line there with an absolute path (of the directory containing the lib), then running ldconfig -v ... See ldconfig(8)
I would suggest adding /usr/local/lib into /etc/ld.so.conf and making a symlink from /usr/local/lib/libfoo.so to e.g. $HOME/libfoo.so etc... (then run ldconfig ...). I don't think adding a user specific directory to /etc/ld.so.conf is reasonable ...
PS. What you really want is to package your application (e.g. as a *.deb package for Debian or Ubuntu, or an *.rpm for Fedora or Redhat). Package management systems handle dependencies!

What actually is $RPM_BUILD_ROOT?

In the process of building an RPM package, I have to specify the BuildRoot and later will be used in %install which invovles $RPM_BUILD_ROOT. I always think that $RPM_BUILD_ROOT is the fake installation for RPM to perform packaging. Then, at install time using the RPM package, it will install into actual location. For example:
$RPM_BUILD_ROOT/usr/bin
I thought that $RPM_BUILD_ROOT is for the packaging process only, and in some ways RPM can distinguish the $RPM_BUILD_ROOT and the actual install location when the user performs "rpm -ivh package.rpm" will be /usr/bin.
But recently upon reading some documents, it is suggested that $RPM_BUILD_ROOT is the actual location which will be installed, and the $RPM_BUILD_ROOT is specified by user with the setting of environment variable $RPM_BUILD_ROOT in order to let the users install the package in their desire locations. Otherwise, $RPM_BUILD_ROOT will be null and it will install into the default location. In the above case, it is /usr/bin . Thus, $RPM_BUILD_ROOT is not just for packaging or "fake installation" process, but is a way for user to define install location, similar to select folder location in Windows.
I don't know my thinking is correct or not. Can someone please verify? Thanks in advance.
$RPM_BUILD_ROOT (or the equivalent %{buildroot} SPEC file macro) always holds the directory under which RPM will look for any files to package. The RPM scripts (e.g. the script that compresses the manual pages) will also use that value to know where to look for the files that were just installed. Normally, this value will be non-empty and contain a location away from the system directories - usually somewhere under /tmp or /var/tmp.
The author of the SPEC file is expected to make sure that make install (or whatever installer the software in question is using) will place any files under $RPM_BUILD_ROOT, with the same hierarchy that should be used when the software is finally installed. E.g. to have RPM install ls in /bin/ls, the %install SPEC file section should make sure that ls is placed in $RPM_BUILD_ROOT/bin/ls.
The author of the SPEC file is also expected to use the BuildRoot: tag to specify a proper location. Alternatively, the build system could have an rpmrc RPM configuration file with a proper entry. In any case the build root should be set, so that:
Normal users will be able to build the source package.
Should the superuser ever build the source package, the build process will not clobber any system files, unless the superuser installs the resulting binary package. And yes, there may be a good reason to build some packages as root - for example, running the full glibc testsuite requires root privileges for some tests.
That said, RPM can and will build a package with an empty build root variable. In that case both the build install and the final destination locations will coincide. A potential call to e.g. make install will use the default locations, thus clobbering the system files under e.g. /usr/lib if run with sufficient privileges. Additionally, having /usr/bin/* in your %files section will happily pull the whole contents of the build host /usr/bin/ directory into your binary package.
Bottom line:
Never use an empty build root.
Do not build packages as root unless there is absolutely no other way.
the file ~/.rpmmacros defines the paths per user:
%_topdir %(echo $HOME)/rpmbuild
%_tmppath %{_topdir}/tmp
and one can also define them with rpmbuild command line parameters:
rpmbuild --define '_topdir /home/username/rpmbuild'

Installation and maintenance of multiple versions of OpenCV (applicable to any other 3rd party library as well)

I have been trying to do build and use OpenCV 2.3.0 on my Fedora15 Lovelock 64bit machine.
Background:
First, on my 64bit Fedora15, OpenCV2.2.0 seems to be in the locations namely
/usr/share/opencv
/usr/doc
/usr/lib64 &
/usr/bin
I do not find the include files though (in /usr/include). This means that the development package was n t installed. My package manager does not list the development packages when i try to Add/remove software.
I have a need to create applications, some of which just link to 2.2 and others which link to 2.3.O of the OpenCV library.So, I thought the best solution would be to have a separate location for 3rd party libraries that i use for my development . So I created a directory in /local named soft and created an OpenCV directory. A directory structure like this one.
/local/soft/
OpenCV/
OpenCV2.2.0/
source-files
build
OpenCV2.3.0/
source-files
build
installation
share/opencv
doc
include
lib
Now, i tried building OpenCV2.3.0 and i succeeded. I configure CMake to use CMAKE_INSTALL_PREFIX to the directory named "installation" (see above), instead of the default /usr/local/. Clean. huh?
I tried building and installing OpenCv 2.2.0 in the same way. Alas 2.2.0 complains something during the build. So i thought i ll link to the already existing version in the standard locations. BUT, when i try to install the dev packages for 2.2 using my package manager,the development files for x86_64 are not found :-) which means i dont have the headers to link to the libraries in the standard location.
I cant build my executable since linker ld would not find the OpenCV that i have installed in the non-standard location.(although i point it to the exact location using the -L and -l options with gcc in my Eclipse).
Question 1: Am i doing the right thing in maintaining installations in non-standard locations? Is /usr/ the standard location where the package manager will always do the installation?
Question2 : What is the right way of linking to these libraries installed in non-standard locations? Why would not ld recognize my .so files in the lib folder?
sudo g++ logpolar.cpp -o logpolar.o -I /local/soft/OpenCV/opencv2.3.1/installation/include/ -l/local/soft/OpenCV/opencv2.3.1/build/lib/libopencv_core.so
But ld canot find -l/local/soft/OpenCV/opencv2.3.1/build/lib/libopencv_core.so
I checked the lib folder and there sure is a beautiful symbolic link to libopencv_core.so.2.3
The standard approach is to use /usr/local directory structure that already has predefined paths like /usr/local/bin, /usr/local/sbin, /usr/local/include, /usr/local/lib.
You put your software here and everything will JustWork(TM). Every Linux distro (incl. Fedora) is set up so it will load programs (libraries, headers) from this libraries.
If you would use GNU toolchain (autoconf, automake => autotools) you would be fine. With CMake you probably need to setup paths for /usr/local/include and /usr/local/lib.
On the other hand this approach wont let you use multiple versions. You can only have one. The one in /usr/local overrides the system one (installed in /usr/bin) because these paths goes first.
You can keep your approach, it is nothing incorrect. We usually put such a software in the /opt folder, so you would go for /opt/opencv/X.Y where X.Y are the version numbers.
Q2: Read the gcc man page and search for the -L option. You need something like:
gcc ... -I/opt/opencv/2.0/include -lsystem_lib -L/opt/opencv/2.0/lib -lopencv ... ...
Do not forget to set LD_LIBRARY_PATH when running programs in multiple versions to properly load correct version:
LD_LIBRARY_PATH=/opt/opencv/2.0/lib /opt/opencv/2.0/bin/opencv

How to use CMake to update library path?

I am writing a shared library for GNU/Linux, which will install for now with "sudo make install". I have CMake recipes to create the files and install them in '/usr/local/lib/app', and the libraries and links are created correctly.
But the library path is not updated and I must run "sudo ldconfig /usr/local/lib/app' manually to make the library available.
Several other packages on my system put their libraries in a specific folder under /usr/local/lib, so I am assuming that's proper.
How then to have CMake update the library path for the system as well as create the files and install them? What is the proper way to do this?
I'd also like it accomplished so that the library path update survives a system restart.
Thanks,
bcw
I'd also like it accomplished so that the library path update survives a system restart.
I'm not aware of any CMake-specific facility. However, you should be able to add rules such as the following in order to make the change persistent.
echo "/usr/local/bret/lib" > /etc/ld.so.conf.d/bret-i386.conf
echo "/usr/local/bret/lib64" > /etc/ld.so.conf.d/bret-x86_64.conf
/sbin/ldconfig
You'll still need to re-run the ldconfig when you overwrite files in bret/lib{,64}.

Resources