On 11/14/2011 09:15 PM, Robert Dailey wrote: > On Mon, Nov 14, 2011 at 1:59 PM, Michael Hertling <mhertl...@online.de>wrote: > >> On 11/14/2011 06:17 PM, Robert Dailey wrote: >>> Well maybe you can tell me I'm doing this wrong then, but based on how I >> am >>> currently setting up my third party libraries, it is required. >>> >>> So basically all third party libraries we use are not installed >>> individually, instead we have a server on our intranet that contains >>> precompiled versions of all libraries in a specific and consistent >>> hierarchy. For this reason, it doesn't make sense to use find_library(), >>> which would normally always give you absolute paths to your library files >>> and thus link_directories() would not be needed. >>> >>> Instead I have a script in CMake that iterates each third party library >> and >>> adds its lib link directory to a list. When done I take this whole list >> of >>> link directories and pass it to link_directories() in my top level >>> CMakeLists file, this way each and every project will include all of the >>> third party library lib directories to have access to them. >> >> Instead of populating a list with the libraries' directories, you might >> set up one variable for each library containing the latter's full path, >> e.g. ZLIB_LIBRARY or BDB47_LIBRARY. Since you do this in the top-level >> CMakeLists.txt, these variables propagate to subordinate CMakeLists.txt >> files and, thus, will be known wherever they are needed in your project. >> >>> For each target I simply create a list of my libs, like so: >>> >>> set( libraries zlib libbdb47 ) >> >> SET(libraries ${ZLIB_LIBRARY} ${BDB47_LIBRARY}) >> >>> I pass each one of these to target_link_libraries() and I leave it up to >>> the compiler to search for where to find the file in the provided link >>> directories. >> >> An unrestricted use of LINK_DIRECTORIES() means asking for trouble; >> especially with numerous directories, there's a growing probability >> that the -L option will lure the linker into a wrong directory some >> day. There're even situations which can't be resolved with -L/-l at >> all: Suppose you have a directory x with liba.so and libb.so, and a >> directory y with different versions of lib{a,b}.so. Suppose further >> you want to link against x/liba.so and y/libb.so. How do you achieve >> this with LINK_DIRECTORIES() and TARGET_LINK_LIBRARIES()? Reversely, >> insisting on the use of LINK_DIRECTORIES() limits the possibilities >> how to organize the libraries on your intranet server. IMO, these >> are actual drawbacks. OTOH, you must know the libaries' locations >> to use LINK_DIRECTORIES(), and the libraries must be known anyway, >> so why not join the locations to the libraries and use full paths? > > > Problem is, if I end up using find_library(), I will have to provide hint > search directories for each and every single library, and there are about > 20 of them. This to me is the same as just generating a list of directories > and including those directly, and a lot less trouble.
As David has outlined in the meantime, the advice is not about using FIND_LIBRARY() - which has not been mentioned a single time - but to assemble full paths from the libraries' directories and the libraries themselves, instead of collecting the directories and passing them to LINK_DIRECTORIES(). I doubt that the latter really means less trouble. > find_library() is great and I really wanted to use it for this, but to me > the benefits of using it diminish when we are not using third party > libraries installed in a non deterministic location. If a user installs the > third party libraries in different locations on each of their machines, and > different versions, it makes more sense to use it in that case. Even if your third-party libraries' organization isn't subject to change, so you don't need to use FIND_LIBARRY(), you might set up variables with the libraries' full paths in the cache, i.e. using SET(... CACHE FILEPATH ...), and preferably initialize them with a separate file and the -C option. In this way, you do not need to hard-code any paths in your project, and the user gains the chance to manipulate each path on the command line or the GUI. > Why should I let CMake search & find a library when I already know where it > is? Simply to get absolute paths to those libraries? If I want absolute > paths I can think of much better ways to do it, preferably through string > concatenation. Exactly; do this to get full paths to your libraries, use these paths in TARGET_LINK_LIBRARIES() and eliminate LINK_DIRECTORIES() from your project. Besides, "knowing where it is" means an assumption of your project on your system's administrational/organizational setup, and relying on such an assumption means that you can't change this setup without risking your project's breakage. Finally, LINK_DIRECTORIES() dramatically increases this risk because it makes your project subtly vunerable to changes in the third-party libraries' directory hierarchy. > Another issue is that 80% of the libraries we use do not have a > pre-packaged Find module provided by CMake. This means I'd end up writing > 80% of the find modules myself. This is a lot of work for no perceived > benefit. Find modules are for FIND_PACKAGE(), and no one says that there must be a find module for each of your third-party libraries. > With my points made and circumstances explained, can you still give me a > good reason to use find_library? FIND_LIBRARY() has the secondary advantage that it automatically searches for libraries in a platform-dependent manner through a platform-independent interface, e.g. it can search for .lib files as well as for .so files without the user's intervention. For this reason, I often use FIND_LIBRARY() - in conjunction with PATHS and NO_DEFAULT_PATH - even in configuration files for FIND_PACKAGE(), which definitely know where the requested library is located. > I understand and agree with the issues that come with using > link_directories(), however I haven't run into those issues yet and our > consistent organization of third party libraries on our intranet server are > carry over from our legacy build system that I'm replacing. In this regard, the point is that using LINK_DIRECTORIES() - due to its inherent booby-traps - restricts the possibilities to change the third-party libraries' organization on your intranet server. If you are willing to accept such a restriction, it's okay, of course. IMO, it's completely unnecessary because the use of full paths in cached variables - regardless if set up by FIND_LIBRARY() or initialized via -C - makes your project by far more robust w.r.t. the external libraries and provides additional means for the user to intervene. Regards, Michael -- Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://www.cmake.org/mailman/listinfo/cmake