如何正确使用CMake创建一个依赖于自定义库的复杂项目

huangapple go评论55阅读模式
英文:

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 包含了所有内容。我觉得将 HEADERSSOURCES 分开会更清晰,我还会使用小写字母。不需要 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.

huangapple
  • 本文由 发表于 2023年2月19日 15:20:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75498575.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定