Search code examples
c++windowsg++static-librariesstatic-linking

How to write a static C++ library and link it to an executable using g++ on Windows 10?


main.cpp

#include <iostream>

int main() {
    std::cout << "main()" << std::endl;
    foo();
    return 0;
}

foo.cpp

#include <iostream>

extern "C" {
  void foo() {
      std::cout << "bar" << std::endl;
  }
}

Compile static library:

$ g++ foo.cpp -static

Error:

undefined reference to `WinMain'

But this compiles:

$ g++ foo.cpp -shared -o foo.lib

Now I have a static library named foo.lib (supposedly).

I try to compile an executable that links to it:

$ g++ -L -lfoo main.cpp -o main.exe

And get this error:

'foo' was not declared in this scope

But foo is declared in the static library that I'm linking with. If the link works, I don't think I need to declare it in main.cpp also. So why isn't the link working?


Update.

I added void foo(); to main.cpp so it doesn't complain that foo needs to be declared.

#include <iostream>

void foo();

int main() {
    std::cout << "main()" << std::endl;
    foo();
    return 0;
}

So I try to compile again and I get this new error:

undefined reference to `foo()'

Why would I need to define foo in main.cpp? It's already defined in foo.cpp which is the static library.

If I have to define foo in main.cpp that defeats the entire purpose of linking to the library foo.lib.

UPDATES

  • Removing all the extern "C" { ... } lines doesn't make the "foo is undefined" errors go away.

Solution

  • What follows are the magical incantations you seek:

    • main.cpp
    #include <iostream>
    extern void foo();
    int main() { 
      std::cout << "main()" << std::endl; 
      foo();
    } 
    
    • foo.cpp
    #include <iostream>
    void foo() { 
      std::cout << "bar" << std::endl; 
    }
    

    Console commands:

    $ g++ -o foo.obj -c foo.cpp
    
    $ ar rcs foo.lib foo.obj
    
    $ g++ main.cpp foo.lib -o main.exe
    

    These spells conjure up the static lib foo with the executable main statically linked to it.