I am generating Visual Studio files with CMake for C++. I have project A and project B that depend on a self-made library.
main_folder
CMakeLists.txt
|- build
|_ Libfolder
| CMakeLists.txt
|_ Proj_A_folder
| CMakeLists.txt
|_ Proj_B_folder
CMakeLists.txt
I am adding all of them as subdirectories (and they should be since I am also still working on the said library). However, running cmake ..
from the build directory the first time generates:
CMake 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
linked by target "Proj_A" in directory C:/CodeAmber/main_folder/Proj_A_folder
linked by target "Proj_B" in directory C:/CodeAmber/main_folder/Proj_B_folder
The .sln file has generated, and I can then open it, build Mylib, and run cmake ..
again, and it works. However, that behaviour is not nice of course. I want it to see the dependency correctly and always build the Mylib first (preferably also on the compilation of proj_A and B automatically).
If I build the Mylib by hand, and then execute cmake ..
, the CMake call then completes successfully but does not actually build the project A and B themselves to .exe. That is also something I do not understand, how to trigger this?
I have searched a lot for answers, but most have a very different project folder structure or use External_Project
(I'm still working on the library, so this is not useful). The answers I did find say that just target_link_libraries
is enough to create a dependency. However, I think if find_library
does not find anything in the first place, that causes the problem. However, I have not been able to find a solution, and I also do not understand why other than the visual studio files, it does not actually build my executable.
Also, I am relatively new to CMake, so it would be wonderful if you could give an example how to call a command you suggest.
main_folder
# Solution
project(VRshoes_PC_side)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Split in projects of our own software (defining folder names)
set(LIB Libfolder)
set(PROJ_A Proj_A_folder)
set(PROJ_B Proj_B_folder)
add_subdirectory(${LIB})
add_subdirectory(${PROJ_A})
add_subdirectory(${PROJ_B })
Libfolder
cmake_minimum_required (VERSION 3.8)
set(THIS_LIB Mylib)
file(GLOB_RECURSE HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
file(GLOB_RECURSE SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build/) # .dll
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build/) # .lib
set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build/) # .pdb
# Only put SHARED if you ONLY want a DLL. That was my mistake earlier, we need a LIB file too.
add_library(${THIS_LIB} "${HEADERS}" "${SOURCES}")
add_custom_target(alwaysbuild ALL)
target_include_directories(${THIS_LIB} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/ ${CMAKE_CURRENT_SOURCE_DIR}/libraries/include/)
target_link_libraries(${THIS_LIB} PUBLIC setupapi wsock32 ws2_32 bthprops)
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/include" PREFIX "Header Files" FILES ${HEADERS})
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/src" PREFIX "Source Files" FILES ${SOURCES})
target_sources(${THIS_LIB} INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/*.h
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
)
Proj_A_folder
cmake_minimum_required (VERSION 3.8)
# If you disable this, it expects WinMain instead of main as application entry point.
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE /ENTRY:mainCRTStartup")
set(THIS_PROJECT_NAME PROJ_A)
set(LIB_DIR ${PROJECT_SOURCE_DIR}/Libfolder)
# Linking to self made libraries in a project: https://stackoverflow.com/questions/11216408/cmake-dependencies-headers-between-apps-libraries-in-same-project
find_library(LIB NAMES Mylib PATHS ${LIB_DIR}/build/Debug NO_DEFAULT_PATH )
add_executable (${THIS_PROJECT_NAME} WIN32 "main.cpp" "main.h")
target_link_libraries(${THIS_PROJECT_NAME} ${LIB})
target_include_directories(${THIS_PROJECT_NAME} PUBLIC ${LIB_DIR}/include)
EDIT: Based on Tsyvarevs comments, I changed the target_link_libraries to the following, so I now have:
target_include_directories(${THIS_PROJECT_NAME} PUBLIC ${LIB_DIR}/include)
target_link_libraries(${THIS_PROJECT_NAME} PUBLIC Mylib)
This gives an error on running cmake ..
:
CMake Error at Proj_A/CMakeLists.txt:15 (add_executable):
Cannot find source file:
C:/CodeAmber/pc_side_cpp/Lib_folder/*.h
Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
.hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc
Proj_B_folder
# long thing probably requires the same solution.
# just to indicate I don't want to solve it by having my Proj_A in the main folder so I only have two CMakeLists.txt.