Yesterday I was reading a lot about deploying MacOSX applications, but I still have some doubts. I have been deploying Qt4 applications for MacOSX for the past few years using macdeployqt. Now, mi application uses a library that doesn't belong to the Qt framework: Poppler.
I have installed poppler-qt4 using Homebrew :
brew install poppler --with-qt4 --enable-xpdf-headers
After using macdeployqt, I know that I have to use install_name_tool to change the absolute paths by relative paths. Some of the dylibs have also dependencies:
MyApp.app/Contents/MacOS/MyApp:
/usr/local/lib/libpoppler-qt4.4.dylib
/usr/local/lib/libpoppler-qt4.4.dylib:
/usr/local/Cellar/poppler/0.20.5/lib/libpoppler.28.dylib
/usr/local/lib/libfontconfig.1.dylib
/usr/local/lib/QtCore.framework/Versions/4/QtCore
/usr/local/lib/QtGui.framework/Versions/4/QtGui
/usr/local/lib/QtXml.framework/Versions/4/QtXml
After using macdeployqt I know that Qt frameworks have been copied inside the app bundle, How can I change /usr/local/lib/QtCore.framework/Versions/4/QtCore with a relative path using install_name_tool?
Are homebrew dylibs compiled using -headerpad_max_install_names?
Is there an automatic way to do this using brew?
What should I use with install_name_tool? #executable_path or #loader_path?
EDIT: It seems that macdeployqt is smart enough to deploy third party dylibs, poppler-qt4 and all its dependencies are copied to the Applicaciont.app/Frameworks folder, and install_name_tool is used automatically. BUT, now I am suffering this BUG : macdeployqt not copying plugins I suppose that the problem is "qt" on the name of poppler-qt4.4.
You can change by hand all the paths but it is error-prone, long and painful to do.
What I suggest is to use a tool to do it for you: cpack included with cmake.
Anyways since 10.5 you should use: #loader_path. See Dylib.
For MacOS X the following code creates a bundle and copy properly homebrew dylib even with root permissions.
However, you will have to check that every lib compiled with homebrew had the right parameters.
Usually, for deployement it is better to compile by hand the libs. I had some problems with homebrew libs (ffmpeg). But not Qt nor Boost :-).
if( USE_QT5 )
qt5_use_modules( MyApp Core OpenGL Sql Multimedia Concurrent )
endif()
# Install stuff
set( plugin_dest_dir bin )
set( qtconf_dest_dir bin )
set( APPS "\${CMAKE_INSTALL_PREFIX}/bin/MyApp" )
if( APPLE )
set( plugin_dest_dir MyApp.app/Contents/ )
set( qtconf_dest_dir MyApp.app/Contents/Resources )
set( APPS "\${CMAKE_INSTALL_PREFIX}/MyApp.app" )
endif( APPLE )
if( WIN32 )
set( APPS "\${CMAKE_INSTALL_PREFIX}/bin/MyApp.exe" )
endif( WIN32 )
#--------------------------------------------------------------------------------
# Install the MyApp application, on Apple, the bundle is at the root of the
# install tree, and on other platforms it'll go into the bin directory.
install( TARGETS MyApp
BUNDLE DESTINATION . COMPONENT Runtime
RUNTIME DESTINATION bin COMPONENT Runtime
)
#--------------------------------------------------------------------------------
# Install needed Qt plugins by copying directories from the qt installation
# One can cull what gets copied by using 'REGEX "..." EXCLUDE'
install( DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
"${QT_PLUGINS_DIR}/codecs"
"${QT_PLUGINS_DIR}/phonon_backend"
"${QT_PLUGINS_DIR}/sqldrivers"
"${QT_PLUGINS_DIR}/accessible"
"${QT_PLUGINS_DIR}/bearer"
"${QT_PLUGINS_DIR}/graphicssystems"
DESTINATION ${plugin_dest_dir}/PlugIns
COMPONENT Runtime
FILES_MATCHING
PATTERN "*.dylib"
PATTERN "*_debug.dylib" EXCLUDE
)
#--------------------------------------------------------------------------------
# install a qt.conf file
# this inserts some cmake code into the install script to write the file
install( CODE "
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"\")
" COMPONENT Runtime
)
#--------------------------------------------------------------------------------
# Use BundleUtilities to get all other dependencies for the application to work.
# It takes a bundle or executable along with possible plugins and inspects it
# for dependencies. If they are not system dependencies, they are copied.
# directories to look for dependencies
set( DIRS ${QT_LIBRARY_DIRS} ${MYAPP_LIBRARIES} )
# Now the work of copying dependencies into the bundle/package
# The quotes are escaped and variables to use at install time have their $ escaped
# An alternative is the do a configure_file() on a script and use install(SCRIPT ...).
# Note that the image plugins depend on QtSvg and QtXml, and it got those copied
# over.
install( CODE "
file(GLOB_RECURSE QTPLUGINS
\"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/plugins/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
set(BU_CHMOD_BUNDLE_ITEMS ON)
include(BundleUtilities)
fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\")
" COMPONENT Runtime
)
# To Create a package, one can run "cpack -G DragNDrop CPackConfig.cmake" on Mac OS X
# where CPackConfig.cmake is created by including CPack
# And then there's ways to customize this as well
set( CPACK_BINARY_DRAGNDROP ON )
include( CPack )
Related
I'm currently working on a project that is being built using CMake; it is then subsequently packaged up with CPack into an RPM.
The following is packaged into the RPM:
Several Executables
Configuration files
Some more context:
This project is running using OpenMPI, and there are X amount of nodes, depending on user input AND based on the # of nodes the user specifies, X docker containers are spawned.
There are instances of each executable running in tandem on each container
There is an OpenMPI crash and it is difficult to debug without GDB
The executables have been compiled as Release. However, if I want to make debugging possible I have been compiling the CMake project as Debug.
The executables are created as Debug. I have the VERBOSE=1 flag on when making the package and can confirm that -g flag is present, and the executables have debug symbols when loading them into GDB locally
Some lines in the CMakeLists.txt:
# Bunch of compilation lines above
install(TARGETS executable_1 executable_2 executable_3 DESTINATION bin) # Installs the executables into a local bin dir
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_INSTALL_PREFIX /usr)
install(DIRECTORY bin/ DESTINATION /usr/bin)
install(DIRECTORY config/ DESTINATION /etc/PROJECT_NAME FILES_MATCHING PATTERN "*")
# Making of the package
set(CPACK_PACKAGE_NAME "PROJECT_NAME")
set(CPACK_PACKAGE_VERSION 0.1)
set(CPACK_PACKAGE_RELEASE 1)
set(CPACK_GENERATOR "RPM")
set(CPACK_PACKAGE_VENDOR "ME")
set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_PACKAGE_RELEASE}.${CMAKE_SYSTEM_PROCESSOR}")
set(CPACK_RPM_PACKAGE_AUTOREQ 0)
set(CPACK_RPM_PACKAGE_RELOCATABLE True)
include(CPack)
The problem:
When CPack is doing its thing and creating the RPM, the executables can be packaged into the RPM, but the problem is they have improper permissions; aka when the executables are installed on the Containers, they cannot be executed. I can address this by adding:
# Bunch of compilation lines above
install(TARGETS executable_1 executable_2 executable_3 DESTINATION bin) # Installs the executables into a local bin dir
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_INSTALL_PREFIX /usr)
# Permissions Fix
set(PROGRAM_PERMISSIONS_DEFAULT
OWNER_WRITE OWNER_READ OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)
install(DIRECTORY bin/ PERMISSIONS ${PROGRAM_PERMISSIONS_DEFAULT} DESTINATION /usr/bin)
install(DIRECTORY config/ DESTINATION /etc/PROJECT_NAME FILES_MATCHING PATTERN "*")
# Making of the package
set(CPACK_PACKAGE_NAME "PROJECT_NAME")
set(CPACK_PACKAGE_VERSION 0.1)
set(CPACK_PACKAGE_RELEASE 1)
set(CPACK_GENERATOR "RPM")
set(CPACK_PACKAGE_VENDOR "ME")
set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_PACKAGE_RELEASE}.${CMAKE_SYSTEM_PROCESSOR}")
set(CPACK_RPM_PACKAGE_AUTOREQ 0)
set(CPACK_RPM_PACKAGE_RELOCATABLE True)
include(CPack)
After adding the permissions, the permission are fixed, but for some reason the executables that are copied do not have debug symbols anymore; my local executables in the bin/ folder are the proper executables which have symbols, but the executables packaged into the RPM DOT NOT have debug symbols. Meaning somewhere along the way, something really odd is happening.
My question is, why? Either way results in a different problem. I'm wondering if there is a way to make sure the permissions are correct AND the proper executables get copied and packaged into the RPM. Any suggestions would be much appreciated.
Thanks!
Do not use absolute install destinations and do not read CMAKE_INSTALL_PREFIX, if you can avoid it. Using absolute install destinations (possibly indirectly through the use of CMAKE_INSTALL_PREFIX) forces you to run the install target with privileges that allow the process to modify those absolute paths. This usually means you have to use sudo to run the install target, even when installing to a directory owned by the standard user.
Since running cpack involves running the install target with the install prefix replaced with a directory inside the build directory (basically cmake --install ... --prefix ...), you can avoid the need for root privileges, if you use relative install locations.
My preferred the install logic here would be:
# allow the installation into any directory below the file system root
set(CMAKE_INSTALL_PREFIX /)
# set the default executable install location, see https://cmake.org/cmake/help/latest/command/install.html#installing-targets
# Note: could be set "globally", i.e. from the toplevel CMakeLists.txt allowing installation of individual targets
set(CMAKE_INSTALL_BINDIR usr/bin)
install(TARGETS executable_1 executable_2 executable_3 RUNTIME)
#preferrably replace this with install(FILES ... TYPE BIN) to install individual files
set(PROGRAM_PERMISSIONS_DEFAULT
OWNER_WRITE OWNER_READ OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)
install(DIRECTORY bin/ PERMISSIONS ${PROGRAM_PERMISSIONS_DEFAULT} DESTINATION usr/bin)
# preferrably replace this with install(FILES ... TYPE SYSCONFIG)
install(DIRECTORY config/ DESTINATION etc/PROJECT_NAME FILES_MATCHING PATTERN "*")
# Making of the package
...
I assume in your scenario somewhere along the way you got the file permissions incorrect the cmake build / install / package process.
I am trying to install two projects: Foo and NeedsFoo. I have successfully compiled and locally installed Foo using cmake. However, I'm on a server and cmake doesn't appear to "remember" where Foo is.
In the cmake to configure NeedsFoo I have
list(APPEND CMAKE_MODULE_PATH "<prefix>/foo-install/CMake/FOO") # add path to FOOConfig.cmake
find_package(FOO REQUIRED)
if( FOO_FOUND )
MESSAGE(STATUS "Found FOO!")
endif( FOO_FOUND )
MESSAGE(STATUS ${FOO_INCLUDE_DIRS})
"Found Foo!" is printed --- so cmake finds FOO --- but the variable ${FOO_INCLUDE_DIRS} is empty and, therefore, the package does not compile. Any thoughts?
EDIT: There seems to be another copy of Foo installed on the server. Unfortunately, I can't use it (it is the 'master' branch of our project and I need to use my own branch). I tried changing the find_package call to
find_package(FOO REQUIRED PATHS "<prefix>/foo-install/CMake/Foo" NO_DEFAULT_PATH)
but that did not solve the problem.
Make sure the headers are installed, often you'll need to install a -dev or -devel package to get the headers. If they are installed and you can see them in your system, they might be on a path that cmake isn't expecting. Open the findFoo.cmake file (on Linux this will generally be in /usr/share/c make-x.y/modules) and check the list of expected locations, see if you're have installed in a less conventional one.
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.
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.
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)