Providing the project root directory for CMake find_package - c++

When compiling a project on Windows via CMake, which let's say has the Boost library as a dependency, you might do the following:
Run CMake on the project source directory.
It says it can't find Boost, but you can specify ACTUAL_BOOST_ROOT as a CACHE PATH setting,
which will then be picked up and BOOST_ROOT is set, so that FIND_PACKAGE(Boost) can find the
Boost libraries.
I would like to do the same for my own library Straph, but for some reason in my own FindStraph.cmake, I can't pick up the STRAPH_ROOT variable:
# Find Straph library
#
# Once done this will define:
# STRAPH_FOUND - System has Straph
# STRAPH_INCLUDE_DIRS - The Straph include directories
# STRAPH_LIBRARIES - The libraries needed to use Straph
find_path(STRAPH_INCLUDE_DIR straph/straph.h
HINTS
${STRAPH_ROOT}/include
${STRAPH_ROOT}
)
find_library(STRAPH_LIBRARY NAMES straph libstraph
HINTS
${STRAPH_ROOT}/lib
${STRAPH_ROOT}
)
set(STRAPH_LIBRARIES ${STRAPH_LIBRARY})
set(STRAPH_INCLUDE_DIRS ${STRAPH_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Straph DEFAULT_MSG STRAPH_LIBRARY STRAPH_INCLUDE_DIR)
mark_as_advanced(STRAPH_INCLUDE_DIR STRAPH_LIBRARY)
At least that's the way it seems to me: in my CMakeLists.txt I do something like this then:
SET(ACTUAL_STRAPH_ROOT CACHE PATH "Location of Straph library")
IF(EXISTS ${ACTUAL_STRAPH_ROOT})
SET(STRAPH_ROOT ${ACTUAL_STRAPH_ROOT})
ENDIF()
FIND_PACKAGE(Straph REQUIRED)
INCLUDE_DIRECTORIES(${STRAPH_INCLUDE_DIRS})
But it goes and complains that it can't find the libraries even after I set ACTUAL_STRAPH_ROOT.

Related

Do I need a Shared library in a CMAKE project with several subdirectories? How do I do it?

I need to implement a StatisticsLogger library on to a C++/C solution built with cmake and compiled with VS#2010. The project uses the ADTF API, since is built for the ADTF framework.
The solution is composed by different modules/projects, which include their own CMakeLists.txt.
My doubt/problem is regarding the library and Cmake, I need it to be accesible to every single module, but it can't be copied, them all should access the same StatisticsLogger library, that I have implemented with a Singleton.
When I run the framework, the concurrent execution accesses StatsLogger constructor once on each module, like if I had created one StatsLogger on each module, making it unable to trace together all the data I want to log and difficulting file handling.
This is how I added the library in CMakeLists.txt:
add_library(loggerModule
${DSTD_DIR}/dstdfloat.h
${DSTD_DIR}/dstdint.h
${DSTD_DIR}/dstdbool.h
${SUPT_DIR}/logg/statslogger.h
${SUPT_DIR}/logg/statslogger_c_connector.h
${SUPT_DIR}/logg/statslogger_c_connector.cpp
${SUPT_DIR}/logg/statslogger.cpp
)
#set_target_properties(loggerModule PROPERTIES VERSION ${PROJECT_VERSION})
#set_target_properties(loggerModule PROPERTIES PUBLIC_HEADER include/mylib.h)
link_libraries(loggerModule)
It would seem that adding SHARED property to the command add_library would do the job, but Im not capable of getting it working. It returns several link problems.
So, regarding my doubt, Is this the way to get the desired funcionality, to make the library SHARED? What am I doing wrong?
Main CMakeLists.txt:
# CMAKE for test filter build
cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
# Set default install prefix
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR})
# Set project name
project(${PROJECT_NAME})
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Environment checks
find_package(ADTF 2.14.2 REQUIRED)
IF (NOT DEFINED ADTF_FOUND)
MESSAGE( FATAL_ERROR "ADTF was NOT found!!!")
ENDIF()
find_package(ADTF_DISPLAY_TOOLBOX REQUIRED)
IF (NOT DEFINED ADTF_DISPLAY_TOOLBOX_FOUND)
MESSAGE( FATAL_ERROR "ADTF_DISPLAY_TOOLBOX was NOT found!!!")
ENDIF()
set(COMPLETE_PROJECT_BINARY_OUTPUT_DIR ${CMAKE_SOURCE_DIR}/${PROJECT_BINARY_OUTPUT_DIRECTORY})
# Set path to sw module dependencies
set(COMMON_DIR ${CMAKE_SOURCE_DIR}/common)
set(DSTD_DIR ${CMAKE_SOURCE_DIR}/common/dstd)
set(INTF_DIR ${CMAKE_SOURCE_DIR}/common/intf)
set(SUPT_DIR ${CMAKE_SOURCE_DIR}/common/supt)
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
#option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
include_directories(${DSTD_DIR})
include_directories(${SUPT_DIR}/logg)
add_library(loggerModule SHARED
${DSTD_DIR}/dstdfloat.h
${DSTD_DIR}/dstdint.h
${DSTD_DIR}/dstdbool.h
${SUPT_DIR}/logg/statslogger.h
${SUPT_DIR}/logg/statslogger_c_connector.h
${SUPT_DIR}/logg/statslogger_c_connector.cpp
${SUPT_DIR}/logg/statslogger.cpp
)
#set_target_properties(loggerModule PROPERTIES VERSION ${PROJECT_VERSION})
#set_target_properties(loggerModule PROPERTIES PUBLIC_HEADER include/mylib.h)
link_libraries(loggerModule)
# Set commands for BB nodes generation
# ...and dependencies for generation
# Go into sub-directory with filter sources
add_subdirectory(${CMAKE_SOURCE_DIR}/tool/adtf/af_acca)
#[33 other add_subdirectories commands]
Example subdirectory CMakeLists.txt:
# External required components have to be provided with path variables
# Internal required components have to be connected to the source file list
if(NOT DEFINED DSTD_DIR)
message( FATAL_ERROR "AF_CDAS requires DSTD_DIR" )
endif()
if(NOT DEFINED INTF_DIR)
message( FATAL_ERROR "AF_CDAS requires INTF_DIR" )
endif()
if(NOT DEFINED SUPT_DIR)
message( FATAL_ERROR "AF_CDAS requires SUPT_DIR" )
endif()
set(CDAS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../)
include_directories(${COMMON_DIR})
[some more includes]
#
# CDAS FILES
#
set(CDAS_FILES
${CDAS_DIR}/src/cdas/cdas.c
${CDAS_DIR}/src/cdas/cdas.h)
source_group("cdas\\files" FILES ${CDAS_FILES})
#
# CDAS ADTF WRAPPER
#
set(CDAS_ADTF_WRAPPER
${CDAS_DIR}/tool/adtf/af_cdas/af_cdas_conf.h
${CDAS_DIR}/tool/adtf/af_cdas/af_cdas.h
${CDAS_DIR}/tool/adtf/af_cdas/af_cdas.cpp)
source_group("cdas\\adtf" FILES ${CDAS_ADTF_WRAPPER})
adtf_add_filter(CDAS
# List source and header files of your filter and its required components
# ${MAIN_FILES}
${CDAS_FILES}
${CDAS_ADTF_WRAPPER}
)
# stdafx.h workaround
if (MSVC)
set_target_properties(CDAS PROPERTIES COMPILE_FLAGS "/Y-")
endif(MSVC)
# MANDATORY PATH SETTING !!!
install (TARGETS CDAS DESTINATION ${COMPLETE_PROJECT_BINARY_OUTPUT_DIR}/debug CONFIGURATIONS Debug)
install (TARGETS CDAS DESTINATION ${COMPLETE_PROJECT_BINARY_OUTPUT_DIR}/release CONFIGURATIONS Release)
adtf_set_folder(CDAS filter)
When using this files, I get the following error:
LINK : fatal error LNK1181: cannot open input file '......\Release\loggerModule.lib' [C:\Users\inno\Desktop\rad
ar_processing\test\adtf\build\win64_vc100\tool\adtf\af_aoca\AOCA.vcxproj]
There isn't any loggerModule.lib in the Release folder, but a loggerModule.dll. In the Debug folder there is a .lib, but copying it to Release won't solve the problem.
I never got too familiar with Cmake, and I am trying to learn it, so I don't know what is going on here, if I am doing something wrong, or my approach wasn't good from the beggining.

How to make cmake find a shared library in a subfolder

I'm trying to learn how to make a shared library. And the following seems to work (please comment if you have some feedback to this method, I basically have no idea what I'm doing).
In my library project, I've put the header files into a folder named "include", and the source files into "src".
My library's CMakeLists.txt:
cmake_minimum_required(VERSION 2.4.0)
project(mycustomlib)
# Find source files
file(GLOB SOURCES src/*.cpp)
# Include header files
include_directories(include)
# Create shared library
add_library(${PROJECT_NAME} SHARED ${SOURCES})
# Install library
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
# Install library headers
file(GLOB HEADERS include/*.h)
install(FILES ${HEADERS} DESTINATION include)
My application's CMakeLists.txt:
cmake_minimum_required(VERSION 2.4.0)
project(myprogram)
# Find source files
file(GLOB SOURCES src/*.cpp)
# Create executable
add_executable(${PROJECT_NAME} ${SOURCES})
# Find and link library
find_library(MYCUSTOMLIB mycustomlib)
target_link_libraries(${PROJECT_NAME} ${MYCUSTOMLIB})
And this is working. The problem is that I want to put both the headers and the library into subfolders (specifically: /usr/local/include/mycustomlib/ for the headers, and /usr/local/lib/mycustomlib/ for the library).
So this is my attempt:
My library's new CMakeLists.txt:
cmake_minimum_required(VERSION 2.4.0)
project(mycustomlib)
# Find source files
file(GLOB SOURCES src/*.cpp)
# Include header files
include_directories(include)
# Create shared library
add_library(${PROJECT_NAME} SHARED ${SOURCES})
# Install library
install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME})
# Install library headers
file(GLOB HEADERS include/*.h)
install(FILES ${HEADERS} DESTINATION include/${PROJECT_NAME})
My application's new CMakeLists.txt:
cmake_minimum_required(VERSION 2.4.0)
project(myprogram)
# Find source files
file(GLOB SOURCES src/*.cpp)
# Create executable
add_executable(${PROJECT_NAME} ${SOURCES})
# Find and link library
find_library(MYCUSTOMLIB mycustomlib/mycustomlib)
target_link_libraries(${PROJECT_NAME} ${MYCUSTOMLIB})
And this is not working. Now, I'm forced to specify the .so file of the library like this:
find_library(MYCUSTOMLIB mycustomlib/libmycustomlib.so)
How come?
I'll deal with your actual problem first and offer additional comments after that. Technically speaking, you are asking CMake to find a library named mycustomlib/mycustomlib, but what you really want to say is you want find mycustomlib and it can be found in a subdirectory called mycustomlib. A couple of alternative ways to call find_library() to achieve this for your second case would be:
find_library(MYCUSTOMLIB mycustomlib PATH_SUFFIXES mycustomlib)
find_library(MYCUSTOMLIB mycustomlib PATHS /usr/local/lib/mycustomlib)
The latter is making more assumptions than it should about where you have the library installed, so I'd favour the first option. The first option assumes CMake would already find libraries in /usr/local/lib, which it seems it is from your question. You can influence where CMake looks for libraries by modifying CMAKE_PREFIX_PATH and CMAKE_LIBRARY_PATH. I'd expect either of the above options to make your second case work.
Now to other observations. You've requested a very old minimum CMake version in the first line of each of your CMakeLists.txt files. You probably want to consider at the very least making this 2.8 (personally, I'd suggest more like 3.2 or later, but it depends on what your project needs to support).
You have used file globbing to obtain your list of sources and headers. This is not robust and should generally be avoided (see a discussion of this here). You will see plenty of example code use method this for simplicity, but it is not recommended for real world projects (the CMake documentation even says not to use it). Explicitly list out your source and header files individually if you want robust builds.
If you are happy to require CMake 2.8.11 or later (and you should be these days), rather than calling include_directories() which makes everything pick up the header search path you specified, you should prefer to attach the search path requirement to the target that needs it. You do this with target_include_directories(). The equivalent of your code above would be:
target_include_directories(${PROJECT_NAME} PUBLIC include)
This gives much better control of your inter-target dependencies as your project grows in size and complexity. For a more in-depth discussion of this topic, see this article and perhaps also this one (disclosure: I wrote both articles).
Are your library and program totally separate source code repositories? Can they be built in the same project? You can build multiple targets in one CMakeLists.txt file. The project name doesn't have to have any relationship to the names of any of the targets (you often see the PROJECT_NAME variable re-used for the target name in simple examples, which is unfortunate since it suggests a relationship between the two, but for all but simple projects this won't be the case). If they are in the same repository, building them together would be a much simpler build since you wouldn't have to install the library for the executable to find it and link to it.
If they must be built in separate projects, then something like the following for the application's project should get you close:
cmake_minimum_required(VERSION 2.8.11)
project(myprogram)
# List your program's sources here explicitly
add_executable(myprogram src/foo.cpp src/bar.cpp)
# Find and link library
find_library(MYCUSTOMLIB mycustomlib PATH_SUFFIXES mycustomlib)
target_link_libraries(myprogram PUBLIC ${MYCUSTOMLIB})
# Find library's headers and add it as a search path.
# Provide the name of one header file you know should
# be present in mycustomlib's include dir.
find_path(MCL_HEADER_PATH mycustomlib.h PATH_SUFFIXES mycustomlib)
target_include_directories(myprogram PUBLIC ${MCL_HEADER_PATH})
For extra points, you could try to confirm that the header path is in the same area as the library by checking the common path prefix, or you could just derive
the MCL_HEADER_PATH from the MYCUSTOMLIB path by assuming a directory structure. Both approaches have advantages and drawbacks. If you want to explore the latter, the get_filename_component() command will be your friend.
Hopefully that points you in the right direction.

How to get a header only library portably from version control using CMake?

For a typical C++ header only library located on, e.g., github, at: https://github.com/username/library_name,
has a directory structure with an include/library_name folder like:
include/library_name
containing all the library sources. This is typically installed by users to, e.g., under Linux: /usr/local/include/library_name.
I need a cmake script for using the library in external projects portably (across Linux, MacOs, BSD, Windows).
It should:
find if the library is installed, if the version is over a threshold, use the installed library
otherwise, get the library from github, configure it as an external project, and put it in the system include path so that it can be used by the project as if it were installed.
What is the correct way of achieving this with CMake?
I finally got it to work, this FindLibraryName.cmake tries to find the library and if it doesn't find it, gets it from github and sets it up as an external project:
# Find the Library_Name include directory
# The following variables are set if Library_Name is found.
# Library_Name_FOUND - True when the Library_Name include directory is found.
# Library_Name_INCLUDE_DIRS - The path to where the poco include files are.
# If Library_Name is not found, Library_Name_FOUND is set to false.
find_package(PkgConfig)
# Allow the user can specify the include directory manually:
if(NOT EXISTS "${LIBRARY_NAME_INCLUDE_DIR}")
find_path(LIBRARY_NAME_INCLUDE_DIR
NAMES library_name/library_name.hpp
DOC "Library_Name library header files"
)
endif()
if(EXISTS "${LIBRARY_NAME_INCLUDE_DIR}")
include(FindPackageHandleStandardArgs)
mark_as_advanced(LIBRARY_NAME_INCLUDE_DIR)
else()
include(ExternalProject)
ExternalProject_Add(library_name
GIT_REPOSITORY https://github.com/username/library_name.git
TIMEOUT 5
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
INSTALL_COMMAND "" # Disable install step, is a header only lib!
)
# Specify include dir
ExternalProject_Get_Property(library_name source_dir)
set(LIBRARY_NAME_INCLUDE_DIRS ${source_dir}/include)
endif()
if(EXISTS "${LIBRARY_NAME_INCLUDE_DIR}")
set(Library_Name_FOUND 1)
else()
set(Library_Name_FOUND 0)
endif()
Then in the projects CMakeLists.txt, just add:
find_package(Library_Name)
include_directories(${LIBRARY_NAME_INCLUDE_DIRS})
You can replace GIT with SVN above and provide the URL of an svn repo and it will work as well. Other version control systems are also available.

How to work around CMake + XCode 4 paths dependencies?

I have projects structured like so:
Libs/
Apps1/
Apps2/
In each folder is a CMakeLists.txt. I would like to generate a project file for each of the folders, and each AppsN references Libs. My method of doing that is by calling CMake's add_subdirectory(../Libs/Source/LibN) etc.
Now when I do this, CMake says add_subdirectory must specify a unique absolute path for the binary output folder.
See this post:
Xcode dependencies across different build directories?
XCode can not handle dependencies when the build output folder is unique per target. It needs one folder. And CMake does this by default, it just refuses to when the folder is not a subdir.
I tried altering and changing the output path after the target is created. This will build the objects to the output folder, XCode sees them, but all references to this target in the CMake script will use the unique path.
Proposed solutions are:
include project files in App1/Projects/Subdir and duplicate projects in an irrelevant location
reorganize my folders to a shared parent folder to avoid this CMake craziness, which presents some security problems for me (as some dirs are not public)
never refer to the target by its CMake name, instead using the shared path name. Not sure how to do this properly
try and get this patched on the CMake side somehow
switch to premake
Try to add the following to the root CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
PROJECT (ContainerProject)
SET (LIBRARY_OUTPUT_PATH ${ContainerProject_BINARY_DIR}/bin CACHE PATH
"Single output directory for building all libraries.")
SET (EXECUTABLE_OUTPUT_PATH ${ContainerProject_BINARY_DIR}/bin CACHE PATH
"Single output directory for building all executables.")
MARK_AS_ADVANCED(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH)
# for common headers (all project could include them, off topic)
INCLUDE_DIRECTORIES(ContainerProject_SOURCE_DIR/include)
# for add_subdirectory:
# 1) do not use relative paths (just as an addition to absolute path),
# 2) include your stuffs in build order, so your path structure should
# depend on build order,
# 3) you could use all variables what are already loaded in previous
# add_subdirectory commands.
#
# - inside here you should make CMakeLists.txt for all libs and for the
# container folders, too.
add_subdirectory(Libs)
# you could use Libs inside Apps, because they have been in this point of
# the script
add_subdirectory(Apps1)
add_subdirectory(Apps2)
In Libs CMakeLists.txt:
add_subdirectory(Source)
In Source CMakeLists.txt:
add_subdirectory(Lib1)
# Lib2 could depend on Lib1
add_subdirectory(Lib2)
In this way all Apps could use all libraries. All binary will be made to your binary ${root}/bin.
An example lib:
PROJECT(ExampleLib)
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
SET(ExampleLibSrcs
...
)
ADD_LIBRARY(ExampleLib SHARED ${ExampleLibSrcs})
An example executable (with dependency):
PROJECT(ExampleBin)
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${ExampleLib_SOURCE_DIR}
)
SET(ExampleBinSrcs
...
)
# OSX gui style executable (Finder could use it)
ADD_EXECUTABLE(ExampleBin MACOSX_BUNDLE ${ExampleBinSrcs})
TARGET_LINK_LIBRARIES(ExampleBin
ExampleLib
)
Here is a stupid and working example.

splitting a project into a library and a application

I'm using cmake for my project. No I want to split some parts into a library and use this for 2 different applications.
Now I don't how how to do this subprojects in cmake. My first attempt was to use the add_subdirectory command:
cmake_minimum_required(VERSION 2.8)
add_subdirectory(MSI)
message("Building MsiQtWizard with: ${MSI_INCLUDE_DIR}")
add_subdirectory(MsiQtWizard)
So MSI would be my library. Inside the MSI folder is another cmakelists which is basically a standalone list for building the library. I thought I could make the MsiQtWizard project also a standalone cmakelists, so I could theoretically build MSI and use the library to build MsiQtWizard (and other projects).
The cmakelists in the root directory would just be a helper to build the library and the GUI in one single step.
The problem is, for building MsiQtWizard, I need the include path to msi and the static library binaries. I tried to do something like that at the end of MIS/CMakelists.txt:
### Set variables, other scripts may use ###
SET(MSI_INCLUDE_DIR include)
MESSAGE("Include directory is: ${MSI_INCLUDE_DIR}")
and in the MsiQtWizard/CMakelists:
##### external libraries #####
#MSI
find_path(MSI_INCLUDE_DIR REQUIRED msi/Image.hpp
PATH_SUFFIXES MSI/include include)
My intend is, that MsiQtWizard will search for msi, if the varaible was not previously set (so that you could use this cmakelists as a standalone). When building MSI, I want to save the include path (and later binary locations) and pass it to MsiQtWizard - but the value is gone as soon as I'm back in my root cmakelists.
So that is, what I tried. My Question is now: How would I correctly split my project into a library and a (later multiple) application and can I do it in a way that I can also build them independently?
Or, more specific: How can I pass values from a node CMakelist to the root CMakeList (like I tried with MSI_INCLUDE_DIR)?
If your building a library - its best to completely separate it from the application build. Otherwise you are coupling your library with your application with cmake, which in my view defeats the purpose of building a library.
When building your library you will want something like
project (MSILibrary)
ADD_LIBRARY(MSILibrary src/MSI1.cpp src/MSI2.cpp)
install (TARGETS MSILibrary DESTINATION lib)
where src contains your library code. You can then make then sudo make install your library to your standard library location (e.g. /usr/lib).
You can then use your library in any subsequent project. Put these in a new directory and create a new CMakeLists.txt for them.
You will want something like,
#include find modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
project (MSI-project-1)
find_package(MSILibrary REQUIRED)
IF(MSILibrary_FOUND)
include_directories(${MSILibrary_INCLUDE_DIRS}
ENDIF(MSILibrary_FOUND )
target_link_libraries (MSI-project-1 ${MSILibrary_LIBRARIES})
install (TARGETS MSI-project-1 DESTINATION bin)
Now all you need to do is help cmake find you library.
You can include a module for this. In the file ./cmake/Modules/FindMSILibrary.cmake type something like:
# - Try to find MSILibrary library
# Once done, this will define
#
# MSILibrary_FOUND - system has MSILibrary
# MSILibrary_INCLUDE_DIRS - the MSILibrary include directories
# MSILibrary_LIBRARIES - link these to use MSILibrary
## Google this script (I think its fairly standard, but was not bundled with my CMAKE) - it helps find the macros.
include(LibFindMacros)
# Dependencies
libfind_package(MSILibrary)
# Use pkg-config to get hints about paths
libfind_pkg_check_modules(MSILibrary_PKGCONF MSILibrary)
# Include dir
find_path(MSILibrary_INCLUDE_DIR
NAMES MSI.hpp
PATHS ${MSI_Library_PKGCONF_INCLUDE_DIRS}
)
# Finally the library itself
find_library(MSILibrary_LIBRARY
NAMES MSILibrary
PATHS ${MSILibrary_PKGCONF_LIBRARY_DIRS}
)
# Set the include dir variables and the libraries and let libfind_process do the rest.
# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
set(MSILibrary_PROCESS_INCLUDES MSILibrary_INCLUDE_DIR MSILibrary_INCLUDE_DIRS)
set(MSILibrary_PROCESS_LIBS MSILibrary_LIBRARY MSILibrary_LIBRARIES)
libfind_process(MSILibrary)
That should be it.
EDIT:
If you really want to package your applications with your library (perhaps some example applications), then you can do something like so:
In your root CMakeLists.txt
cmake_minimum_required (VERSION 2.6)
project (MSIProject)
# The version number.
set (MSIProject_VERSION_MAJOR 0)
set (MSIProject_VERSION_MINOR 1)
set (MSIProject_PATCH_LEVEL 3 )
# project options
OPTION( BUILD_SHARED_LIBS "Set to OFF to build static libraries" ON )
OPTION( BUILD_EXAMPLES "Set to OFF to skip building the examples" ON )
# Put the libaries and binaries that get built into directories at the
# top of the build tree rather than in hard-to-find leaf
# directories.
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
##########################################################################
# Build the library
##########################################################################
add_subdirectory(MSI-src)
##################
# Build your example Apps if requested
############
IF( BUILD_EXAMPLES )
add_subdirectory(example/MSI-project-1)
add_subdirectory(example/MSI-project-2)
ENDIF( BUILD_EXAMPLES )
Your library MSI-src/CMakeFiles.txt will be as before, and your example/MSI-project-1/CMakeLists.txt will be something like
## Make the InferData example project
project (MSI-project-1)
#include MSI library
include_directories ("${MSILibrary_SOURCE_DIR}/include")
#include the includes of this project
include_directories ("${MSI-project-1_SOURCE_DIR}/../include")
#build
add_executable(MSI-project-1 src/P1.cpp)
target_link_libraries (MSI-project-1 MSILibrary) #link
install (TARGETS MSI-project-1 DESTINATION bin)