CMake's add_executable
requires providing at least one source file. I find this requirement very strange and I don't see any justification for it.
Before I will continue with illustrating example let me emphasis that I'm not asking for a way around this problem (a trivial one is to use an empty source file as show below). Also I'm not asking for being persuaded that not having there any source file is a bad idea.
What I'm asking is what was the reasoning behind CMake's choice. Maybe there is some obstacle that I just don't know about?
Sources
Let's consider a simple example where we have command line application with plugins to do some actions.
The plugins will be provided by static libraries.
Then we also have a framework for command line tool provided by static library as well. A framework only since it doesn't have the crucial part - action done by plugin.
Finally producing the application is just joining those two static libraries.
plugin.hpp - plugin interface header
#ifndef PLUGIN_HPP
#define PLUGIN_HPP
int invoke_plugin(char const* command);
#endif
my_plugin.cpp - a sample implementation of a plugin
#include <cstdlib>
#include <iostream>
int invoke_plugin(char const* command)
{
std::cout << "my_plugin invoking command >" << command << "<\n";
return EXIT_SUCCESS;
}
main.cpp - program framework
#include "plugin.hpp"
#include <cstdlib>
int main(int argc, char* argv[])
{
if(argc == 2)
return invoke_plugin(argv[1]);
else
return EXIT_FAILURE;
}
Building
Below I show sample steps to build such configuration in both g++ (I used g++ 5.4.0 from Cygwin) and Visual C++ (from 2013 Express).
Both produce what is expected, a running application. And with that approach I can produce various plugin libs and just link them with the framework lib to make new applications with new functionalities.
g++
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
Visual C++
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
This however will not work with CMake. Following 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
)
results in following error (CMake 3.6.2, under 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!
Workaround
There is a trivial workaround. You just have to make an empty source file and add it to add_executable
. Then it works just fine.
Why?!
But why does CMake puts such a requirement?
It doesn't seem to make it any simpler for CMake.
It doesn't seem to make it any simpler for CMake users. Even if the scenario shown here is not probable and has a simple workaround it is still some issue.
So what's the point behind CMake making such a requirement?