What are these commands used in the following section when using the libxl library? - excel

It's from the readme section on how to use libxl when I downloaded it and started using it in mingw-w64
What is the use of -I in this command?
What is the use of -L in this command?
What is the use of -lxl in this command?
I can't figure out what they mean and what they do; can anyone help me?
This is an example taken from the library libxl readme section.

This is a command to invoke Gnu's C++ compiler on the 'generate.cpp' source code file to create an executable named generate.exe.
-I../../../include.cpp says to look 3 directories above the current one for an Include file named include.cpp.
-lxl says to search the "xl" library when the linking loader runs and -L../../../bin says you might find the "xl" library in the bin folder three levels above the current directory

Related

SCons: When adding a Node to the LIBS variable, how do I make it use just the file without the directory?

I have SCons code in which I am using SConscripts to build different directories separately. In my Src directory, my SConscript builds a shared library, and then returns the resulting Node as the Python variable libMyLibrary. I typically use the install option to copy this library to a directory that is on my system's LD_LIBRARY_PATH (I'm using OpenSUSE).
So far, so good. Now, in another directory, Src/Test, another SConscript imports libMyLibrary and builds some Programs using code like this:
env.Program('myProgram', 'myProgram.cpp', LIBS=[env['LIBS'], libMyLibrary])
The program then gets installed to my local bin folder. This code does track the library dependency and build the program, but the problem is that since the library is in a sub-directory (Src), that sub-directory gets included in the linker command. Here is an abbreviated example of the linker command that SCons generates:
g++ -o Src/Test/myProgram Src/Test/myProgram.o Src/libMyLibrary.so
I believe this happens because the Node,libMyLibrary, is essentially a path. The problem is that when I try to run the program, it is not looking for libMyLibrary.so in my library folder, but rather Src/libMyLibrary.so, and of course it doesn't find it.
I do NOT want the libraries I build to be installed in sub-directories of my install folder.
I already add the Src folder to LIBPATH, so SCons adds the -LSrc option to the linker command, but that doesn't solve the problem. My preference would be that when I add a Node, the path should automatically get parsed out to add the appropriate -L and -l options.
I know that I can get around this problem by adding the string 'MyLibrary' to the LIBS variable instead of the libMyLibrary Node, but then I have to explicitly tell SCons that each Program Depends() on libMyLibrary. It seems very inefficient to short-circuit SCons's built-in dependency tracking this way. Does anyone know the correct, SCons-y way to do this?
I'm referring to your latest comment: It looks to me as if this is not really a SCons problem, but more a general linker question (XY problem). Are you perhaps simply searching for RPATH? Please also check this old SO question: scons executable + shared library in project directory

CMake: How to execute a command before make install?

This is the way I install the config files:
file(GLOB ConfigFiles ${CMAKE_CURRENT_SOURCE_DIR}/configs/*.xml
${CMAKE_CURRENT_SOURCE_DIR}/configs/*.xsd
${CMAKE_CURRENT_SOURCE_DIR}/configs/*.conf)
install(FILES ${ConfigFiles} DESTINATION ${INSTDIR})
But I need to convert one of the xml files before installing it. There is an executable that can do this job for me:
./Convertor a.xml a-converted.xml
How can I automatically convert the xml file before installing it? It should be a custom command or target that installing depends on it, I just don't know how to make the install command depend on it though. Any advice would be appreciated!
Take a look at the SCRIPT version of install:
The SCRIPT and CODE signature:
install([[SCRIPT <file>] [CODE <code>]] [...])
The SCRIPT form will invoke the given CMake script files during
installation. If the script file name is a relative path it will be
interpreted with respect to the current source directory. The CODE
form will invoke the given CMake code during installation. Code is
specified as a single argument inside a double-quoted string.
For example:
install(CODE "execute_process(\"./Convertor a.xml a-converted.xml\")")
install(FILES a-converted.xml DESTINATION ${INSTDIR})
Be sure to checkout the entry for execute_process in the manual. Also be aware that macro expansion inside the CODE parameter can be a bit tricky to get right. Check the generated cmake_install.cmake in your build directory where the generated code will be placed.
I think that your specific case would work better if you were to use a custom command and target like so:
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/a-converted.xml
COMMAND ./Convertor a.xml a-converted.xml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Convertor
)
add_custom_target(run ALL
DEPENDS ${CMAKE_BINARY_DIR}/a-converted.xml
COMMENT "Generating a-converted.xml" VERBATIM
)
install(
FILES ${CMAKE_BINARY_DIR}/a-converted.xml
DESTINATION ${INSTDIR}
)
Note: I don't have all the details, so the directories are probably
not exactly what you'd want in your environment, although it's
a good idea to generate files in the ${CMAKE_BINARY_DIR} area.
That way you can be sure that the file a-converted.xml is built at the time you want to install it. Especially, these two rules make sure that if you make changes to the file, it gets recompiled.

How to manage development and installed versions of a shared library?

In short: This question is basically about telling Linux to load the development version of the .so file for executables in the dev directory and the installed .so file for others.
In long: Imagine a shared library, let's call it libasdf.so. And imagine the following directories:
/home/user/asdf/lib: libasdf.so
/home/user/asdf/test: ... perform_test
/opt/asdf/lib: libasdf.so
/home/user/jkl: ... use_asdf
In other words, you have a development directory for your library (/home/user/asdf) and you have an installed copy of its previous stable version (/opt/asdf) and some other programs using it (/home/user/jkl).
My question is, how can I tell Linux, to load /home/user/asdf/lib/libasdf.so when executing /home/user/asdf/test/perform_test and to load /opt/asdf/lib/libasdf.so when executing /home/user/jkl/use_asdf? Note that, even though I specify the directory by -L during link, Linux uses other methods (for example /ect/ld.so.conf and $LD_LIBRARY_PATH) to find the .so file.
The reason I need such a thing is that, of course the executables in the development directory need to link with the latest version of the library, while the other programs, would want to use the stable version.
Putting ../lib in the library path doesn't seem like a secure idea, not to mention not completely correct since you can't run the test from a different directory.
One solution I thought about is to have perform_test link with libasdf-dev.so and upon install, copy libasdf-dev.so as libasdf.so and have others link with that. This solution has one problem though. Imagine the following additional directory:
/home/user/asdf/tool: ... use_asdf_too
Which gets installed to:
/opt/asdf/bin: use_asdf_too
In my solution, it is unknown what use_asdf_too should be linked against. If linked against libasdf.so, it wouldn't work properly if invoked from the dev directory and if linked against libasdf-dev.so, it wouldn't work properly if invoked from the installed location.
What can I do? How is this managed by other people?
Installed shared objects usually don't just end with ".so". Usually they also include their soname, such as libadsf.so.42.1. The .so file for development is typically a symlink to a fully-versioned filename. The linker will look for the .so file and resolve it to the full filename, and the loader will then load the fully-versioned library instead.

What is the right place for FindXXX.cmake files for locally compiled libs?

I have a lib I installed by hand (to /usr/local) on a Linux system (Eigen3, by the way). There is a FindEigen3.cmake bundled with the lib but that is not installed anywhere by default.
There is /usr/share/cmake-x.y/Modules where CMake looks for additional modules, but putting these files there doesn't seem the way to do things. Is there an equivalent place under /usr/local that is also scanned by default? Or what is the standard way of creating custom library modules?
(Although the question isn't strictly connected to programming, I think library authors may also encounter the same question from the other side: where to put these files when installing manually.)
In our project we place FIndXXX.cmake modules in folder project root dir/cmake/modules. For this to work you have to specify in project root dir/CMakeLists.txt (similiar to what DLRdave has already said):
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
See the comments in the CMake documentation for the "find_package" command:
http://cmake.org/cmake/help/v2.8.8/cmake.html#command:find_package
It speaks of writing a "project-config" file, and where to install it, such that find_package(Eigen3) will work without having a FindEigen3.cmake find module... It is verbose, but the information is in there.
See also user contributed wiki pages such as this one:
https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/How-to-create-a-ProjectConfig.cmake-file
You need to set the CMAKE_MODULE_PATH to include the directory that the FindEigen3.cmake file is in before calling find_package. I believe that:
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} <your path> )
will do the trick, but I do not have a setup to test that available at the moment so you may have to massage that technique a bit.

How to build libcurl.so with a different target name?

I am using libcurl for my utility and its working very well till now for all Linux platforms. I downloaded, unzipped and simply followed the instructions given without any changes. My product uses the libcurl.so file and is linked dynamically. The .so file is bundled along with our product. Recently there were issues in Suse wherein we found that Libcurl is bundled by default and there was a conflict in installation.
To avoid this issue we tried renaming the libcurl.so into libother_curl.so but it did not work and my binaries still show libcurl.so as a dependency through ldd. I had since learnt that the ELF format of linux shared objects specifies the file name hardcoded as SO file name in the headers.(I could verify the same with objdump -p).
Now my question is what is the simplest way to go? How do I build a libcurl with a different name? My original process involves running configure with the following switches
./configure --without-ssl --disable-ldap --disable-telnet --disable-POP3 --disable-IMAP --disable-RTSP --disable-SMTP --disable-TFTP --disable-dict --disable-gopher --disable-debug --enable-nonblocking --enable-thread --disable-cookies --disable-crypto-auth --disable-ipv6 --disable-proxy --enable-hidden-symbols --without-libidn --without-zlib
Make
Then pick the generated files from /lib/.libs
Are there any Configure Switches available wherein I can specify the target file name? Any specific Makefile I could change?
I tried changing in what I thought could be obvious locations but either could not generate the libs or were generated with the same name.
Any help is much appreciated.
I got the answer from the curl forums(Thanks Dan). Basically we have to use the makefile.am as a starting point to go through a list of files and change the library name "libxxx_curl".
$find . -name Makefile.am |xargs sed -i 's/libcurl(.la)/libxxx_curl\1/g'
$buildconf
$configure
$make
I lot of commercial applications bundle their particular library versions in a non standard path and then tweak environment variable LD_LIBRARY_PATH in a launch script so to avoid conflict. IMHO it is better than trying to change the target name.

Resources