Search code examples
c++compilationstatic-libraries

How to implement parts of member functions of a Class in a static library while the rest functions implemented in a cpp file?


I have a C++ Class A like this:

// in header file A.h
class A
{
public:
    void foo1();
    void foo2();
private:
    double m_a;
};


// in cpp file A1.cpp
void A::foo1(){
    m_a = 0;  //do something with m_a
}

// in cpp file A2.cpp
void A::foo2(){
    foo1();  // call foo1
}

// in cpp file main.cpp
int main(){
    A obj;
    obj.foo2();
    return 0;
}

In my occasion, the function foo1 and foo2 are implemented by two different people. For some reasons, I need to hide the implementation of foo1 so that the people who code A2.cpp cannot fetch the source code of foo1, and at the same time he can use Class A in his own application (like main.cpp above).

I tried to archive A1.cpp as a static library, and of course, an 'unresolved external symbol' error for foo2 occurred.

I built my static library using CMake plugins in Visual Studio 2019, and my CMakeLists.txt is like:

add_library (my_lib STATIC A1.cpp)
target_include_directories(my_lib PUBLIC path/to/A.h)

Is there any solution or workaround for this issue?


Solution

  • You can compile A1.cpp without linking, which will give you a compiled object file, A1.o. You can hand this off, so the developers for A2.cpp won't be able to see the source, but will be able to link your object file to build the final project.

    With g++, that could look like:

    A.h

    class A
    {
    public:
        void foo1();
        void foo2();
    private:
        double m_a;
    };
    

    A1.cpp

    #include "A.h"
    #include <iostream>
    
    void A::foo1() {
        std::cout << "foo1 called!" << std::endl;
        m_a = 72;
    }
    

    A2.cpp

    #include "A.h"
    #include <iostream>
    
    void A::foo2() {
        std::cout << "foo2 called!" << std::endl;
        foo1();
    }
    

    main.cpp

    #include "A.h"
    
    int main() {
        A a;
        a.foo2();
    }
    

    Building the project

    If you're using g++, then...

    g++ -c A1.cpp
    

    This will compile but not link A1.cpp, giving you the object file A1.o. You can hand that file off so that the other developers can build the whole project with

    g++ main.cpp A1.o A2.cpp