CMake's add_executable
需要提供至少一个源文件。我发现这个要求非常奇怪,我认为没有任何理由。
在我继续说明示例之前,让我强调一下我并不是要求解决这个问题(一个简单的方法就是使用一个空的源文件,如下图所示)。此外,我并不是要求说服没有任何源文件是一个坏主意。
我问的是CMake选择背后的原因是什么。也许有一些我不知道的障碍?
让我们考虑一个简单的示例,其中我们使用插件执行命令行应用程序来执行某些操作。
插件将由静态库提供。
然后我们还有一个静态库提供的命令行工具框架。一个框架,因为它没有关键部分 - 插件完成的操作。
最后生成应用程序只是加入这两个静态库。
plugin.hpp - 插件界面标题
#ifndef PLUGIN_HPP
#define PLUGIN_HPP
int invoke_plugin(char const* command);
#endif
my_plugin.cpp - 插件的示例实现
#include <cstdlib>
#include <iostream>
int invoke_plugin(char const* command)
{
std::cout << "my_plugin invoking command >" << command << "<\n";
return EXIT_SUCCESS;
}
main.cpp - 程序框架
#include "plugin.hpp"
#include <cstdlib>
int main(int argc, char* argv[])
{
if(argc == 2)
return invoke_plugin(argv[1]);
else
return EXIT_FAILURE;
}
下面我将展示在g ++(我使用的是Cygwin的g ++ 5.4.0)和Visual C ++(来自2013 Express)中构建此类配置的示例步骤。
两者都产生了预期的,正在运行的应用程序。通过这种方法,我可以生成各种插件库,并将它们与框架lib链接起来,以创建具有新功能的新应用程序。
g++ -c my_plugin.cpp -o my_plugin.o
ar rcs libmy_plugin.a my_plugin.o
g++ main.cpp -o main.o
ar rcs libmain.a main.o
g++ -L./ -lmain -lmy_plugin -o my_app
cl /EHsc /MDd -c ../src/my_plugin.cpp
lib my_plugin.obj
cl /EHsc /MDd -c ../src/main.cpp
lib main.obj
link /MACHINE:X86 /SUBSYSTEM:CONSOLE /OUT:my_app.exe main.lib my_plugin.lib msvcrtd.lib
然而,这不适用于CMake。关注CMakeLists.txt
:
add_library(my_plugin STATIC my_plugin.cpp)
add_library(main STATIC main.cpp plugin.hpp)
add_executable(my_app)
target_link_libraries(my_app
PRIVATE main
PRIVATE my_plugin
)
导致跟随错误(CMake 3.6.2,在Cygwin下):
CMake Error at CMakeLists.txt:4 (add_executable):
add_executable called with incorrect number of arguments
CMake Error at CMakeLists.txt:5 (target_link_libraries):
Cannot specify link libraries for target "my_app" which is not built by
this project.
-- Configuring incomplete, errors occurred!
有一个简单的解决方法。您只需创建一个空的源文件并将其添加到add_executable
。然后就可以了。
但为什么CMake提出这样的要求?
似乎没有让CMake更简单。
似乎没有让CMake用户更简单。即使这里显示的场景不太可能并且有一个简单的解决方法,它仍然是一个问题。
那么CMake制定这样一个要求背后的意义是什么?