Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake: Is it possible to build an executable from only static libraries and no source?

Tags:

cmake

I would like to build an executable from static libraries (i. e. .a-files) only. This is possible, because the main() function is contained in one of these libraries.

The add_executable() function requires me to provide at least one source file. But this is not what I want to do.

like image 283
dubbaluga Avatar asked Dec 11 '15 23:12

dubbaluga


People also ask

What does CMake Add_library do?

Adds a library target called <name> to be built from the source files listed in the command invocation. The <name> corresponds to the logical target name and must be globally unique within a project.

Why is CMake necessary?

CMake handles the difficult aspects of building software such as cross-platform builds, system introspection, and user customized builds, in a simple manner that allows users to easily tailor builds for complex hardware and software systems.

How do I add a library to CMake?

Linking libraries to executables with CMake Let's start by adding the library's directory as a subdirectory to our myapp project. add_subdirectory makes the library test defined in libtestproject available to the build. In target_link_libraries we tell CMake to link it to our executable.

Is CMake easy?

Using CMake is simple. The build process is controlled by creating one or more CMakeLists. txt files in each directory (including subdirectories) that make up a project. Each CMakeLists.


2 Answers

There is no way to do it without a hack. You need at least one *.c or *.cpp file.

What I do is make a dummy null.cpp file (zero bytes) and use that. You can also use /dev/null but that only works on Linux.

file(WRITE null.cpp "")

add_executable(tester
    null.cpp
)

target_link_libraries(tester
    -Wl,--whole-archive
    libtest1
    libtest2
    libtest3
    libtest4
    -Wl,--no-whole-archive
    gtest_main
)
like image 89
Mark Lakata Avatar answered Oct 22 '22 04:10

Mark Lakata


There are mainly two reasons why a source file is enforced by CMake:

  1. To determine the LINKER_LANGUAGE from the file ending(s)
  2. Not all compilers do support an object/library only link step (for details see below)

And if you move the main() function to library please keep the following in mind: Why does the order in which libraries are linked sometimes cause errors in GCC?

So if you build the libraries with CMake in the same project, I would recommend to change your libraries (at least the one containing your main() function) to an object library:

cmake_minimum_required(VERSION 2.8.8)

project(NoSourceForExe)

file(WRITE main.cc "int main() { return 0; }")

add_library(MyLibrary OBJECT main.cc)
add_executable(MyExecutable $<TARGET_OBJECTS:MyLibrary>)

The add_library() documentation lists a warning here:

Some native build systems may not like targets that have only object files, so consider adding at least one real source file to any target that references $<TARGET_OBJECTS:objlib>.

But those are rare and listed in Tests/ObjectLibrary/CMakeLists.txt:

# VS 6 and 7 generators do not add objects as sources so we need a
# dummy object to convince the IDE to build the targets below.
...
# Xcode does not seem to support targets without sources.

Not knowing which host OS(s) you are targeting, you may just give it a try.

References

  • CMake Object Lib containing main
  • CMake/Tutorials/Object Library
like image 42
Florian Avatar answered Oct 22 '22 06:10

Florian