Home > database >  C - Why is a Static Library unusable without source files?
C - Why is a Static Library unusable without source files?

Time:11-11

So from what I understand, a static compiled mylib.a file should just be usable as plug-and-play. But I can't use it without the source code, I'm trying to avoid that.

I adapted this tutorial to compile using CMake with the following directory structure:

/
   lib
      libmy_math.a
   main.cpp
   my_math.h
   my_math.cpp
   CMakeLists.txt

The contents of the files are exactly as in the tutorial. The only added file is CMakeLists.txt which basically just runs the library compiling part before building:

CMakeLists.txt

cmake_minimum_required(VERSION 3.21)
project(Test)

### Uncomment this ONCE to compile a libmy_math.a file
# add_library(my_math STATIC my_math.cpp)

add_executable(Test main.cpp)

find_library(MY_MATH_LIB my_math HINTS ./lib)
target_link_libraries(Test PUBLIC ${MY_MATH_LIB})

As the CMake file says, uncommenting Line 5 compiles the library, which is then linked to my code when compiling.

I'm trying to package my code so that I don't show my client the source code for the compiled library (my_math), but if I delete the my_math.h and my_math.cpp files, I get a "file not found" error on import:

/Users/Joe/Desktop/Test/main.cpp:1:10: fatal error: 'my_math.h' file not found
#include "my_math.h"
         ^~~~~~~~~~~


I thought you could compile libraries without needing the source code. What am I missing here?

CodePudding user response:

A static library does not contain each and every definition a header can contain - think of macros, etc. Thus you still need the header. However, you don't need the .cpp anymore to link the library.

CodePudding user response:

Besides the problem stated in Iorro's answer the find_library call here will not work as expected.

find_library(MY_MATH_LIB my_math HINTS ./lib)
target_link_libraries(Test PUBLIC ${MY_MATH_LIB})

What this does is, while running CMake, look for the my_math.a file. However, at that point of the build process, my_math.a has not been built yet. You're just running CMake for the first time, so all you have is source files. Nothing has been compiled yet.

What you want to do instead is link to the library target directly, as CMake already knows about that and can resolve the dependency on its own. So you need to replace the two lines above with:

target_link_libraries(Test PUBLIC my_math)

This now introduces a curious asymmetry in how your test consumes the library (as it is part of the same build) vs. how your clients consume the same library (which are not part of the same build and thus need to do a find_package call before they can use it). Look at CMake's config-file packages for a mechanism that allows you to restore symmetry here, at the cost of a significant amount of boilerplate required in your CMake script.

  • Related