'CMake with custom install path and multiple libraries in different directories

I am new to cmake, I know a lot of similar questions are asked, but I don't seem to figure out how to do this.

I have very large project which can be simplified with this structure:

Parent_dir
   --src
      --main1.cpp
      --main2.cpp.
   --include
      --lib_dir_1
         --f1.cpp
         --f1.h
      --lib_dir_2
         --f2.cpp
         --f2.h
   --build
   --install
      --include
      --share
      --lib
      --bin

I do not have access to /usr/include, /usr/lib, /usr/bin, and /usr/share because it is an account on a cluster. My idea was to run cmake in build dir and install library .o and executives in install dir. My CMakeFile.txt are:

Parent_dir/CMakeFile.txt
    cmake_minimum_required(VERSION 3.13)
    set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
    project(MyProject VERSION 2.0)
    set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install")
    set(CMAKE_CXX_STANDARD 17)   
    add_subdirectory("include/")
    add_subdirectory(src)

Parent_dir/include/CMakeFile.txt
    add_subdirectory(lib_dir1)
    add_subdirectory(lib_dir2)

Parent_dir/src/CMakeFile.txt
    add_executable(M1 Main1.cpp)
    target_include_directories(M1 PUBLIC "${CMAKE_SOURCE_DIR}/include/lib_dir1")
    find_library(LIB_1 lib1)
    target_link_libraries(M1 lib1)
    install (TARGETS M1 DESTINATION ${CMAKE_INSTALL_PREFIX})     
    #add_executable(M2 Main2.cpp)
    #target_include_directories(M2 PUBLIC "${CMAKE_SOURCE_DIR}/include/lib_dir2")
    #find_library(LIB_2 lib2)
    #target_link_libraries(M2 lib2)
    #install (TARGETS M2 DESTINATION ${CMAKE_INSTALL_PREFIX})

Parent_dir/include/lib_dir1/CMakeFile.txt
    add_library(lib1 SHARED f1.cpp f1.h) 
    FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
    INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
    TARGET_LINK_LIBRARIES(lib1 ${Boost_LIBRARIES})
    target_include_directories(lib1 PUBLIC ${CMAKE_CURRENT_LIST_DIR})


Parent_dir/include/lib_dir2/CMakeFile.txt
    add_library(lib2 SHARED f2.cpp f2.h) 
    target_include_directories(lib2 PUBLIC ${CMAKE_CURRENT_LIST_DIR})
    find_library(LIB1 lib1)
    target_link_libraries(lib2 lib1)

At the moment I am only testing building M1 that depends on lib1, I commented stuff referring to M2 executable. I know that find_library(LIB1 lib1) should find lib1 library and put its path to LIB1 variable, so clearly I am making a mistake when targeting and linking because for example in Parent_dir/src/CMakeFile.txtit should be target_link_libraries(M1 ${LIB1}), but I am getting an error: `The following variables are used in this project, but they are set to NOTFOUND. Please set them or make sure they are set and tested correctly in the CMake files: LIB_1.

So find_library never found lib1, if I link as in files above, cmake is fine, make is fine, make install is fine, and in install directory I see M1 executable which does not work when used stating that error while loading shared libraries: liblib1.so: cannot open shared object file:...

So clearly I messed something up and I've been running in circles for two days. Biggest issue with online resources is that a lot of tutorials don't cover the issue how to navigate installation to custom dirs. Note that I have built other packages with typical configure --prefix approaches before and my desire to have install/include share lib bin directories is simply due to previous experience, in CMakeFiles above I only tried to navigate executable M1 to install dir, it worked, but I have no idea where lib1.so is built and whether I messed everything in CmakeFiles.

Also I am not sure if the code structure I am making is "good", perhaps I should move lib1_dir and lib2_dir to src? Problem is that in these libraries I have 100s of files so the structure above made most sense.

PS: I do not have cmake-gui, cluster has 3.15 and 2.18 version and gui only exists for 2.18 version.

UPDATE:

Managed to get installation to work (check answer below), but some issues still remain:

Executables are now in install/bin, library files are in install/lib. I am just not sure if everything is linked properly, both lib1 and lib2 need to be shared libraries as I have about 6 executables that need them. The xml resource is needed by lib1, I don't know how to change the code to look for it other than the current dir. I could set its location to install/bin, but that is a bit dirty as if someone installs the package on other machine, the path to file would be different. I doubt that CMAKE environment variables work within C++?

I would also like to have all .h files from both libraries in install/include dir, how should I go about that?

Can someone explain whether this is correct. I am skeptical with line in src where I link libraries. I did not use find library, because it fails, if I hint it with install/lib location, than it says it cannot find .h files needed by the library. I am suspecting that by doing target_link_libraries(M1 lib1) I am directly recompiling the whole library to attach it to executable, rather than finding existing one and doing simple linking.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source