[CMake] conditional selection of either local "just built" or system versions of a library

Michael Hertling mhertling at online.de
Wed Jan 12 10:54:05 EST 2011


On 01/11/2011 05:46 PM, Marco wrote:
> Dear CMake experts,
> 
> I'm facing the following problem. I have a project with many 
> subdirectories, all at the same hierarchical level:
> 
> /my/project/path/CMakeLists.txt
> /my/project/path/A - include
>                   |- src
>                   |- CMakeLists.txt
> 
> /my/project/path/B - include
>                   |- src
>                   |- CMakeLists.txt
> 
> Each subdir corresponds to a package that a user is allowed to modify 
> and build against a given "general release" already installed centrally 
> or against other locally built packages.
> 
> Some of the executables of package A must be linked against an object 
> file generated by package B. The user could build package B, so that the 
> object file needed by executables in package A is the "local" one, but 
> could also decide to rely on the one that comes from the already 
> installed release.
> 
> To give an example:
> 
> - package A has something like:
>    add_executable(X src/X.cc)
>    target_link_libraries(X ${RIGHTPATH}/ObjFile.o A B C)
>    add_dependencies(X obj_file_target)
> 
> - package B has something like:
>    add_custom_command(
> OUTPUT ${LIBRARY_OUTPUT_PATH}/ObjFile.o
> COMMAND ${CMAKE_CXX_COMPILER}  -Wall
> -I${PROJECT_SOURCE_DIR}/include -c
> ${CMAKE_CURRENT_SOURCE_DIR}/src/ObjFile.cc -o 
> ${LIBRARY_OUTPUT_PATH}/ObjFile.o)
> 
> add_custom_target(obj_file_target DEPENDS ${LIBRARY_OUTPUT_PATH}/ObjFile.o)
> 
> In this way executable X triggers the compilation of ObjFile.o which is 
> put into ${LIBRARY_OUTPUT_PATH}.
> 
> The point is that if the user wants to use the system ObjFile.o located 
> in, say, /Soft/Releases/V1/lib/ObjFile.o I don't have a way to determine 
> for package A the value of RIGHTPATH (either ${LIBRARY_OUTPUT_PATH} or 
> /Soft/Releases/V1/lib/) as the path variable is set when I enter package 
> A which can happen before I enter package B.
> 
> How could I solve this issue? Is there a way to conditionally select 
> which library my exe will be linked against?

You might use a user-supplied path to the external B as indicator:

SET(LIBRARY_OUTPUT_PATH ...)  # Must be known at this place.
SET(RIGHTPATH ${LIBRARY_OUTPUT_PATH})  # Assume internal B.
SET(PATH_TO_B "" CACHE PATH "Path to external B")
IF(PATH_TO_B)
    SET(RIGHTPATH ${PATH_TO_B})  # Use external B.
ENDIF()
ADD_SUBDIRECTORY(A)
IF(NOT PATH_TO_B)
    ADD_SUBDIRECTORY(B)
ENDIF()

So, the user can set PATH_TO_B on the command line or in the GUI to
demand the usage of the external B; if PATH_TO_B is left alone, the
internal B is used. Here, it is crucial that LIBRARY_OUTPUT_PATH is
set in the CMakeLists.txt above B. Because ADD_DEPENDENCIES() isn't
insulted if a prerequisite target doesn't exists, it can remain in
A/CMakeLists.txt without guard regardless whether B/CMakeLists.txt
is processed or not.

Regards,

Michael


More information about the CMake mailing list