Search code examples
c++c++11makefilestdatomic

Undefined reference in static library to c++11 atomic


I have a problem when using a static library that I create beforehand in a project. This static library uses c++11 atomic. Everything compiles well and my static library is created. However, when I try to use it in another project, at link time I got the following error:

 src/engine/bin/libengine.a(Compound.cpp.o): In function`Job::restart()':
 (.text._ZN3Job7restartEv[_ZN3Job7restartEv]+0x30): undefined reference to `__atomic_exchange_1'

Where Compound.cpp.o is when of the object files of the library. Here is the Makefile I am using to create my library:

CC=k1-g++
CPPFLAGS=-c -I$(GENERIC_INCLUDE_DIR) -I$(SPECIFIC_INCLUDE_DIR) -Os -std=c++11 -mos=nodeos 
CXXFLAGS=-c -I$(GENERIC_INCLUDE_DIR) -I$(SPECIFIC_INCLUDE_DIR) -Os -std=c++11 -mos=nodeos 
LFLAGS=-pthread -lnodeos -latomic 

GENERIC_INCLUDE_DIR=generic/include
SPECIFIC_INCLUDE_DIR=specific/include
GENERIC_SRC_DIR=generic/src
SPECIFIC_SRC_DIR=specific/src


LIB = libengine.a
BIN_DIR=bin

vpath %.cpp $(GENERIC_SRC_DIR) $(SPECIFIC_SRC_DIR)
SOURCES := $(wildcard $(GENERIC_SRC_DIR)/*.cpp $(SPECIFIC_SRC_DIR)/*.cpp)
SOURCES := $(notdir $(SOURCES))
OBJECTS := $(patsubst %.cpp,$(BIN_DIR)/%.cpp.o,$(SOURCES))



all: $(OBJECTS) $(LIB)

$(LIB): $(OBJECTS)
    ar -cr $(BIN_DIR)/$@ $^

#$(BIN_DIR)/%.cpp.o: $(GENERIC_SRC_DIR)/%.cpp
#   $(CC) $(CPPFLAGS) $< $(LFLAGS) -o $@

$(BIN_DIR)/%.cpp.o: %.cpp
    $(CC) $(CPPFLAGS) $< $(LFLAGS) -o $@




.PHONY: clean

clean:
    rm -f $(BIN_DIR)/* 

Any thought on this?


Solution

  • It seems that the target platform you're compiling for doesn't support 1-byte atomic instructions natively, so you will need to use the GCC library that provides atomic operations as library functions.

    Link with -latomic to link to GCC's libatomic

    Your makefile tries to do that, but you only use LFLAGS when compiling .o objects, which doesn't do any linking, so the -latomic option is not used when it matters.

    You need to use the -latomic option when compiling the program that uses your static library, not when you create the static library.

    The makefile is a bit of a mess. It's useless to use linker flags when compiling objects, and conventionally CPPFLAGS contains flags for the preprocessor, not compilation flags such as -c and -Os.