【发布时间】:2021-10-18 21:26:03
【问题描述】:
我真的不知道如何准确地表达这个问题,但这是我最好的尝试......
我最近开始从事一个大型项目,我想把它分解成几个组成部分。
以下是其中两个组件的工作原理:
- 第一个组件:它本身是一个可执行程序。由 CMake 制作。获取库代码的一些源文件,并使用
main.cpp文件进行编译和链接。 - 第二个组件:应该使用在第一个组件中编译的相同库,但使用不同的
main.cpp文件,以及一些新库。
本例中的“库”只是包含一些类的头文件和源文件,这些类本身依赖于其他一些库。 (确切地说,是 SDL。)
我想做的是以某种方式让 CMake 编译“第一个组件”并生成一个或多个目标文件,我可以在“第二个组件”中链接到(再次使用 CMake)。
我希望这是有道理的,但它可能并不明显,所以这里有一些进一步的细节:
-
第一个组件使用 SDL 将文本呈现和绘制到 SDL 窗口。我编写的各种类做了很多事情,包括从文件加载字体、在系统上查找字体以及管理 SDL 对象(例如窗口和渲染的文本对象)。
main.cpp文件仅用于测试目的。它允许编译一个可执行文件,证明一切都按预期工作。如果您愿意,可以将其视为测试驱动的开发文件,尽管它不包含任何正式测试。 -
第二个组件依赖于 gcc/g++ 通常会从第一个组件的编译中生成的目标文件。换句话说,我希望能够从第一个组件中获取一些目标文件并使用它们来编译第二个组件。我可以将源文件从第一个组件复制并粘贴到第二个组件,然后从头开始编译所有内容,但这会弄乱我的 git 存储库,而且效率也不高。
我确信必须有可能让 cmake 从第一个组件生成一些目标文件,然后在编译第二个组件时链接这些文件。当然,它可能需要两个单独的 cmake 进程,但这很好。
请注意;我不想编译共享对象。我假设我想要的是静态链接我的目标文件,但是我假设默认情况下 cmake 将调用动态链接过程。换句话说,SDL 库仍然应该是动态链接的。我自己的库不应该动态链接,因为它们在 linux 系统上不可用,它们只能在我自己的 linux 系统上可用。
最小的工作示例?
这是 MWE 有点无意义的事情,但这里仍然是一种尝试。
第一个目录是这样设置的
first/
main.cpp
first.h
first.cpp
CMakeLists.txt
build [d]
第二个目录只包含一个 main.cpp 文件。
CMakeLists.txt:
cmake_minimum_required(VERSION 3.7)
project(testproject)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(SDL2 REQUIRED)
include_directories(testproject ${SDL2_INCLUDE_DIRS})
set(SOURCE_FILES main.cpp first.cpp)
add_executable(testproject ${SOURCE_FILES})
target_link_libraries(testproject ${SDL2_LIBRARIES})
main.cpp:
#include "first.h"
int main()
{
SDL_Init(SDL_INIT_VIDEO);
// using first library in main function
SDL_Window *window = GetWindow();
// doesn't draw anything, but you can
// press the window X to quit
for(bool quit = false; quit == false; )
{
SDL_Event event;
while(SDL_PollEvent(&event) != 0)
{
if(event.type == SDL_QUIT)
{
quit = true;
}
}
}
FreeWindow(window);
SDL_Quit();
return 0;
}
first.h:
#ifndef FIRST_H
#define FIRST_H
#include <SDL2/SDL.h>
SDL_Window* GetWindow();
void FreeWindow(SDL_Window* &window);
#endif // FIRST_H
first.cpp
#include "first.h"
SDL_Window* GetWindow()
{
SDL_Window *window =
SDL_CreateWindow(
"a test window",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
800, 600, SDL_WINDOW_SHOWN);
return window;
}
void FreeWindow(SDL_Window *&window)
{
SDL_DestroyWindow(window);
window = nullptr;
}
这是一个有点奇怪的例子。我试图包含一些非常小的函数,它们会生成一个目标文件以及使用外部 SDL 库。在这种情况下,第二个文件夹实际上可能只是 main.cpp 的副本、头文件的副本或 CMakeLists.txt 中的一行,以告诉 make 系统在哪里找到头文件,然后它应该有一些方法可以找到当前不存在的目标文件,因为第一个 CMakeLists.txt 还没有生成它们。
我不知道该怎么做:
- 首先告诉目录中的 cmake 生成一个目录,其中包含(理想情况下是单个)包含库代码的目标文件,但不包含
main.cpp的目标代码 - 首先告诉第二个目录中的cmake头文件在哪里
- 告诉第二个目录中的cmake,第一个目录生成的库代码的目标文件在哪里,然后如何在第二个将它链接到一个新的main.cpp文件
希望这已经足够清楚了,但这大概是一件不平凡的事情。
【问题讨论】: