I am given several projects (git repos) and each of them depends on a number of libraries (also git repos). Every project has just one target executable and links libraries from other repos.
My file structure:
├── libraries
│ ├── libraryX (git:master)
│ │ ├── build
│ │ │ └── libX.so
│ │ ├── CMakeLists.txt
│ │ ├── fileX.cpp
│ │ └── fileX.h
│ ├── libraryY (git:master)
│ │ ├── build
│ │ │ └── libY.so
│ │ ├── CMakeLists.txt
│ │ ├── fileY.cpp
│ │ └── fileY.h
│ └── libraryZ (git:master)
│ ├── build
│ │ └── libZ.so
│ ├── CMakeLists.txt
│ ├── fileZ.cpp
│ └── fileZ.h
└── projects
├── projectA (git:master)
│ ├── build
│ │ └── outA
│ ├── CMakeLists.txt
│ └── mainA.cpp
└── projectB (git:master)
├── build
│ └── outB
├── CMakeLists.txt
└── mainB.cpp
This is an example CMakeLists.txt file inside libraryX:
cmake_minimum_required(VERSION 3.6)
project(libraryX LANGUAGES CXX)
set(libraries $ENV{LIBRARIES})
set(projects $ENV{PROJECTS})
add_library(libX SHARED fileX.cpp)
target_include_directories(libX PUBLIC ${libraries}/libraryX/)
Currently I am building every library manually, which generates *.so files and then I go to the project and build the executable. This is an example CMakeLists.txt from inside projectA:
cmake_minimum_required(VERSION 3.6)
project(projectA LANGUAGES CXX)
set(libraries $ENV{LIBRARIES})
set(projects $ENV{PROJECTS})
add_executable(outA mainA.cpp)
target_include_directories(outA
PUBLIC
${libraries}/libraryX/
${libraries}/libraryY/
${libraries}/libraryZ/
${projects}/projectA/
)
target_link_libraries(outA
${libraries}/libraryX/build/libX.so
${libraries}/libraryY/build/libY.so
${libraries}/libraryZ/build/libZ.so
)
I am only interested in building/running one project (e.g. projectA/) at a time, but I don't want to manually precompile every library every time I make changes.
Also, I cannot move libraries/ under the project (e.g. projectA/libraries/libraryX) because projectB/ also depends on them, and I don't like having two clones of the same repository in one computer in sibling folders. I also cannot change and rearrange the content of repositories to suit myself, because different teams are working on them and plan to release them as full packages installable from apt-get in the future. Finally, I don't want to use a single top-level CMakeLists.txt inside the workspace because the projects A and B are independent from each other.
I tried looking into add_subdirectory and target_sources but could not understand how to target a source if I want the same library to be used by different executables in projectA and projectB.
Of course, I can run a bash script that builds cmakes in every library, but I thought that this is a job of CMake to do such things. I am clearly not seeing some obvious solution here.
Can anyone help me to force CMake to precompile the library before linking them to the target?
Thanks!
P.S. How can I tell CMake to compile *.dll files instead of *.so, and *.exe instead of Linux binaries?
I have read and watched a lot of tutorials and read a lot of stackoverflow answers about the architecture of the CMake projects. I tried to run the project in Visual Studio on Windows in hopes of it figuring it out itself -- didn't really help. I wrote a bash script that compiles libraries before linking them but it feels wrong, because I was promised that CMake actually does this thing for me. I also tried to use subdirectory system as mentioned in another stackoverflow answer but it did not really succeed.
add_subdirectory, but you already tried. Can you share more details about what happens when you use this command?projectA/outAorprojectB/outB. So, whenever I uselibraryXfromprojectAI have to edit CMakeFiles and vice versa. Or is it ok to name both executables asoutan