CMake link not subfolder

2019-08-09 00:42发布

问题:

I’m new to cmake.

I want to create code to create instances of some classes (like ClassA) and collect them in a handler class. For this i have created a template class Creator. In each class implementation a instance of this class is created with Creator class. (see ClassA.cpp line 8)

I have following folder structure

├── CMakeLists.txt
├── main.cpp
└── SubFolder
    ├── ClassA.cpp
    ├── ClassA.h
    ├── CMakeLists.txt
    └── Creator.h

./main.cpp

#include <iostream>
#include "SubFolder/ClassA.h"

int main(int argc, char **argv) {
   //classA a;

    std::cout << std::endl << "Hello, world!" << std::endl;
    return 0;
}

./CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(teststaticcmake)

add_executable(teststaticcmake main.cpp)
add_subdirectory(SubFolder)
target_link_libraries(teststaticcmake SubFolder)

install(TARGETS teststaticcmake RUNTIME DESTINATION bin)

SubFolder/ClassA.h

#ifndef __CLASSA__
#define __CLASSA__

class classA
{
    public:
        classA();
};
#endif //__CLASSA__

SubFolder/ClassA.cpp

#include "ClassA.h"
#include "Creator.h"

classA::classA()
{
}

classA* pClassA = Creator<classA>::create();

SubFolder/Creator.h

#ifndef __CREATOR__
#define __CREATOR__

#include <iostream>

template<typename T>
class Creator
{
    public:
        static T* create()
        {
            T* p = new T();

            // Do Something here
            // ... like output
            std::cout << std::endl << "created: " << p;

            return p;
        }
};
#endif //__CREATOR__

SubFolder/CMakeLists.txt

add_library(SubFolder ClassA.cpp)

I compile this project and run it. So I get only the output "Hello, world!".
When I remove the comment (main.cpp line 5) a instance of ClassA is used. So I get also the output of class Creator. The code for ClassA is linked.
When I move the class ClassA to root directory it works also.

I have also tried to use parameters like PUBLIC_LINK, debug and general for target_link_libraries. But nothing works.

My intention use a Collection Class in this main.cpp file and get the instanced object from the collection. In the main.ccp file i don't want to know each instanced class because all class ClassA ... ClassZ have the same interface (not shown in this example).

How can i force the link of "unused" code?

Edit: Do don't know if it's neccessary. I use KDevelop4.

回答1:

See How to force gcc to link an unused static library

I've tested your code with GNU 4.8.1 compilers and in your example just replace your target_link_libraries() line with:

target_link_libraries(
    teststaticcmake 
    PRIVATE
        "-Wl,--whole-archive" 
        SubFolder 
        "-Wl,--no-whole-archive"
)

From target_link_libraries() documentation:

  • A link flag: Item names starting with -, but not -l or -framework, are treated as linker flags. Note that such flags will be treated like any other library link item for purposes of transitive dependencies, so they are generally safe to specify only as private link items that will not propagate to dependents.

More References

  • How to force inclusion of an object file in a static library when linking into executable?


标签: c++ linker cmake