Cmake设置将外部c++类添加到项目中

Cmake settings to add external c++ classes to a project

本文关键字:添加 项目 c++ 设置 外部 Cmake      更新时间:2024-09-21

可能有点小问题,请耐心等待。

我想做什么?我有一个名为main.cpp的c++类,我想用它添加RtMidi的外部类。我可以将RtMidi类移到与我的main.cpp相同的文件夹中,并从那里包含它们,但如果我能将它们放在一个单独的文件夹中会感觉干净得多。

RtMidi文件夹有自己的Cmake文件,我的假设是,我可以首先构建该文件夹,创建一个库,然后链接到该库。这是正确的吗?我是c++的新手,不能100%确定这是否是添加外部类的方式。

当试图构建我的项目RtMidi时,我得到了一个警告,即main.cpp文件找不到include。

我正在用Visual Studio代码和clang作为编译器的mac上构建这个,如果这对有帮助的话

main.cpp

#include "RtMidi.h"
int main() 
{
try 
{
RtMidiIn midiin;
} 
catch (RtMidiError &error) 
{
error.printMessage();
}
return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(Music)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include_directories (Project)
add_subdirectory (lib/rtmidi-4.0.0)
file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "src/*.cpp")
add_executable(Music ${SOURCES})
target_link_libraries(Music RtMidi)

生成输出

[main] Building folder: Music 
[main] Configuring folder: Music 
[proc] Executing command: /usr/local/bin/cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++ -H/Users/username/Code/Music -B/Users/username/Code/Music/build -G "Unix Makefiles"
[cmake] Not searching for unused variables given on the command line.
[cmake] -- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE) 
[cmake] CMake Deprecation Warning at lib/rtmidi-4.0.0/CMakeLists.txt:154 (cmake_policy):
[cmake]   The OLD behavior for policy CMP0042 will be removed from a future version
[cmake]   of CMake.
[cmake] 
[cmake]   The cmake-policies(7) manual explains that the OLD behaviors of all
[cmake]   policies are deprecated and that a policy should be set to OLD only under
[cmake]   specific short-term circumstances.  Projects should be ported to the NEW
[cmake]   behavior and not rely on setting a policy to OLD.
[cmake] 
[cmake] 
[cmake] -- Compiling with support for: coremidi
[cmake] -- Configuring done
[cmake] -- Generating done
[cmake] -- Build files have been written to: /Users/username/Code/Music/build
[build] Starting build
[proc] Executing command: /usr/local/bin/cmake --build /Users/username/Code/Music/build --config Debug --target all -- -j 10
[build] Scanning dependencies of target Music
[build] [ 15%] Built target rtmidi
[build] [ 20%] Building CXX object CMakeFiles/Music.dir/src/main.cpp.o
[build] [ 40%] Built target sysextest
[build] [ 40%] Built target qmidiin
[build] [ 50%] Built target apinames
[build] [ 60%] Built target midiout
[build] [ 80%] Built target cmidiin
[build] [ 80%] Built target midiprobe
[build] [ 90%] Built target midiclock
[build] /Users/username/Code/Music/src/main.cpp:5:10: fatal error: 'rtmidi.h' file not found
[build] #include "rtmidi.h"
[build]          ^~~~~~~~~~
[build] 1 error generated.
[build] make[2]: *** [CMakeFiles/Music.dir/src/main.cpp.o] Error 1
[build] make[1]: *** [CMakeFiles/Music.dir/all] Error 2
[build] make: *** [all] Error 2
[build] Build finished with exit code 2

感谢您的帮助,如果这是错误的做法,请为我指明正确的方向来进行

我可以看出你是cmake的新手,这很好。每个人都必须从某个地方开始。

基本上,你没有得到你的"音乐"所需要的适当的包含目录。老实说,如果他们正确地编写了你的项目应该编译的cmake,那么你将其与"RtMidi"联系起来并不是你的错。

以下是您需要的大致代码(假设您所指的包含目录称为inc(

# Where ever that header files resides add it
target_include_directores(Music PRIVATE "lib/rtmidi-4.0.0/.../inc")

========================================

我建议你读";专业版:实用指南;

https://crascit.com/professional-cmake/

如果你想学习写现代生产水平的cmake。由cmake的维护人员之一Craig Scott撰写。

这就是我开始学习cmake的方式,现在我为我的工作编写cmake/C++获得了报酬。

========================================

在网上学习现代cmake几乎是不可能的,因为有太多的错误信息。

例如,不要为源文件进行glob:

file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "src/*.cpp")

相信我,这最终会带来问题。但尽管如此,每个人都在过时的教程中有这一点。

您希望手动列出源文件/头文件,并使用target_sources添加它们。

也不要像这样添加include目录。这是一种非常糟糕的老方法,实际上可能会影响编译时间。

include_directories (Project)

我可以继续谈论我能立即看到的其他糟糕的事情。

=========================================

如果你认为这似乎过于复杂,那么从一开始就应该设计得更好。你是对的。然而,故障不是cmakes。我会责怪C/C++语言没有将构建系统视为该语言的一部分。

现代cmake真是太棒了。我们正在将它用于我们的生产代码库,它真的非常棒。C++可能没有正式的构建系统,但cmake基本上是最接近的东西。

参加聚会有点晚,但今天我在同一个图书馆遇到了这些问题。下面是我针对具体情况的解决方案:使用以下四个shell命令安装RtMidi

git clone https://github.com/thestk/rtmidi.git rtmidi #get the source code on a folder named rtmidi
cd rtmidi #navigate to the folder
cmake -B build #configure cmake build directory 
cmake --build build  # build the project

最后一个命令在你的电脑上导出一个库供cmake查找,所以下一步是将其链接到你的项目。我刚刚在我的cmake 上添加了这些代码行

find_package(RtMidi)
target_link_libraries(target_name RtMidi::rtmidi)

如果你想要的库的cmake是正确的,这是非常标准的,问题隐藏在rtmidi的cmake的第182行target_include_directories(rtmidi PRIVATE这些应该替换为target_include_directories(rtmidi PUBLIC,以便rtmidi正常工作。这是特定库上的一个已知错误,应该在未来的中修复