lundi 12 juin 2023

In C++, is it possible to compile a static library with an extern variable that will be declared by the code that calls the library?

I am trying to adapt someone else's C++ code. It is currently structured as a series of libraries that are statically linked, and eventually called by the main program. Each one of these libraries is compiled using a Makefile. I have hit a problem that I do not understand. Some variables in one of these libraries will only be given values by the main program. These are declared using extern int externValue. However, when I try to compile this part of the code into the library, I get an error saying externValue is an undefined symbol.

The code looks something like this. First the Makefile:

CFLAGS = -g -Wall -O -I/some/file/path/include/ -fpic
LFLAGS = -shared
SRC = source.cc
OBJ = source.o

all: libsource.so

libsource.so: $(OBJ)
    g++ $(CFLAGS) $(LFLAGS) -o libsource.so $(OBJ)

source.o: source.cc
    g++ $(CFLAGS) -c source.cc

the source file source.cc (here passing it for output is just a random action to access the variable):

#include <iostream>
#include "source.h"

extern int externValue;

void testFunc()
{
  std::cout << externValue << std::endl;
}

and the header source.h:

#ifndef __source_h__
#define __source_h__

void testFunc();

#endif

When I run make, I get the following error:

g++ -g -Wall -O -I/some/file/path/include/ -fpic -c source.cc
g++ -g -Wall -O -I/some/file/path/include/ -fpic -shared -o libsource.so source.o
Undefined symbols for architecture x86_64:
  "_externValue", referenced from:
      testFunc() in source.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [libsource.so] Error 1

Am I simply misunderstanding how extern works? Can I compile the libary without a specific value for externValue?

This part of the code will compile if I shift from extern int externValue to int externValue. However, I want to understand how the code was meant to work in the first place, as the source code I was given has produced results in the past. The same approach appears elsewhere in the code. Why deos the code need these variables to be fully declared, rather than just defined, as it is not yet being run.

Aucun commentaire:

Enregistrer un commentaire