英文:
How to properly use CMake to create a complex project with dependencies on custom libraries
问题
I'm trying to create a complex project that becomes a single executable file that uses the following libraries: two libraries BHV and HAL that use one interface library.
我试图创建一个复杂的项目,将其变成一个单一的可执行文件,使用两个库BHV和HAL,它们使用一个接口库。
I have this project structure:
我有这个项目的结构:
Unfortunately, I can't connect the individual libraries to each other.
不幸的是,我无法将这些独立的库连接在一起。
In Interface_lib CMakeList.txt I have this:
在Interface_lib的CMakeList.txt文件中,我有以下内容:
In HAL_lib CMakeList.txt I have this:
在HAL_lib的CMakeList.txt文件中,我有以下内容:
this is the code i use to check_libraries.cmake (from the internet)
这是我用来检查库的check_libraries.cmake代码(来自互联网)
As an output I keep getting the library not found. What am I doing wrong?
作为输出,我一直收到库未找到的错误。我做错了什么?
And is my approach to project structure correct?
我的项目结构方法是否正确?
Thank you.
谢谢。
英文:
I'm trying to create a complex project that becomes a single executable file that uses the following libraries: two libraries BHV and HAL that use one interface library.
I have this project structure:
.
├── BHV
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── CMakeLists.txt
│   ├── include
│   ├── libBHV_Library.so
│   ├── Makefile
│   └── sources
├── HAL
│   ├── check_libraries.cmake
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── CMakeLists.txt
│   ├── include
│   ├── libHAL_Library.so
│   ├── Makefile
│   └── sources
├── Interface
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── CMakeLists.txt
│   ├── include
│   ├── libInterface_Library.a
│   ├── Makefile
│   └── sources
├── CMakeCache.txt
├── CMakeFiles
├── cmake_install.cmake
├── CMakeLists.txt
├── main.cpp
├── Makefile
├── README.md
Unfortunately, I can't connect the individual libraries to each other.
In Interface_lib CMakeList.txt I have this:
cmake_minimum_required(VERSION 3.10)
project(Interface_Library)
#requires at least C++17
set(CMAKE_CXX_STANDARD 17)
# Add all .cpp files from sources folder
file(GLOB SOURCES "sources/*.cpp")
# Add all .h files from include folder
file(GLOB HEADERS "include/*.h")
# Add main.cpp to the project
add_library(Interface_Library STATIC ${SOURCES} ${HEADERS})
In HAL_lib CMakeList.txt I have this:
cmake_minimum_required(VERSION 3.10)
project(HAL_Library)
# requires at least C++17
set(CMAKE_CXX_STANDARD 17)
################################### DIR_MANAGMENT #########################################
# Get the parent directory
get_filename_component(PARENT_DIR ${CMAKE_CURRENT_LIST_DIR} DIRECTORY)
#Set the directory of the parent file as the current directory
set(CMAKE_CURRENT_LIST_DIR ${PARENT_DIR})
message("MYPROJECT_DIR directory: ${CMAKE_CURRENT_LIST_DIR}")
################################### HAL_LIB #########################################
# Add all .cpp files from sources folder
file(GLOB SOURCES "sources/*.cpp")
# Add all .h files from include folder
file(GLOB HEADERS "include/*.h")
# Add main.cpp to the project
add_library(HAL_Library SHARED ${SOURCES} ${HEADERS})
################################### INTERFACE_LIB #########################################
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/Interface)
# Link the Interface_Library into the HAL_Library
target_link_libraries(HAL_Library Interface_Library)
# check if libraries were included
set(TARGET_NAME HAL_Library)
include(check_libraries.cmake)
this is the code i use to check_libraries.cmake (from the internet)
# Get a list of referenced libraries
get_target_property(LINK_LIBS ${TARGET_NAME} LINK_LIBRARIES)
# Print the list of referenced libraries
message("Odkazované knihovny: ${LINK_LIBS}")
# Verify that libraries are available on the system
foreach(LIB ${LINK_LIBS})
execute_process(COMMAND ldd $<TARGET_FILE:${TARGET_NAME}> | grep ${LIB}
RESULT_VARIABLE res
OUTPUT_QUIET ERROR_QUIET)
if(res EQUAL "0")
message("Library ${LIB} was successfully linked with ${TARGET_NAME}")
else()
message(FATAL_ERROR "Error: Library ${LIB} not found.")
endif()
endforeach()
As an output I keep getting the library not found. What am I doing wrong?
And is my approach to project structure correct?
Thank you.
答案1
得分: 0
通常你会这样做:
# ./CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(Interface_Library)
add_subdirectory(HAL)
add_subdirectory(Interface)
# HAL/CMakeLists.txt
file(GLOB srcs sources/*.c include/*.h)
add_library(HAL ${srcs})
target_include_directories(HAL PUBLIC include)
target_link_libraries(HAL PUBLIC Interface)
# Interface/CMakeLists.txt
file(GLOB srcs source/*.c include/*.h)
add_library(Interface ${srcs})
target_include_directories(Interface PUBLIC include)
这就是全部了。只有一个根目录中的 project()
调用。注意你的代码中缺少了 target_include_directories
。注意主根目录的 CMakeLists.txt 包含了所有内容。我觉得将 HEADERS
和 SOURCES
分开会更清晰,我还会使用小写字母。不需要 target_link_directories
,CMake 会找到一切。此外,所有内容都编译为一个大项目,而不是分开编译。
英文:
Typically you do:
# ./CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(Interface_Library)
add_subdirectory(HAL)
add_subdirectory(Interface)
# HAL/CMakeListst.txt
file(srcs GLOB sources/*.c include/*.h)
add_library(HAL ${srcs})
target_include_directories(HAL PUBLIC include)
target_link_libraries(HAL PUBLIC Interface)
# Interface/CMakeLists.txt
file(srcs GLOB source/*.c include/*.h)
add_library(Interface ${srcs})
target_include_directories(HAL PUBLIC include)
That's all. Only one project()
call, in the root. Note the target_include_directories
missing in your code. Note the main root CMakeLists.txt that includes all. I find HEADERS
and SOURCES
separately confusing, I would also use lowercase everything. No target_link_directories
, CMake will find everything. Also, everything is compiled as one big project, not separately.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论