静态库中对 c++11 原子的未定义引用
Undefined reference in static library to c++11 atomic
我在使用预先在项目中创建的静态库时遇到问题。这个静态库使用 c++11 atomic。一切都编译良好,我的静态库已创建。但是,当我尝试在另一个项目中使用它时,在 link 时出现以下错误:
src/engine/bin/libengine.a(Compound.cpp.o): In function`Job::restart()':
(.text._ZN3Job7restartEv[_ZN3Job7restartEv]+0x30): undefined reference to `__atomic_exchange_1'
其中 Compound.cpp.o 是库的目标文件的时间。
这是我用来创建我的库的 Makefile:
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)/*
有什么想法吗?
您正在编译的目标平台似乎本身不支持 1 字节原子指令,因此您将需要使用提供原子操作作为库函数的 GCC 库。
Link 与 -latomic
到 link 到 GCC 的 libatomic
您的 makefile 尝试这样做,但您只在编译 .o
对象时使用 LFLAGS
,它不会执行任何 linking,因此 -latomic
重要的时候不使用选项。
在编译使用你的静态库的程序时需要使用-latomic
选项,而不是在创建静态库时。
生成文件有点乱。在编译对象时使用 linker 标志是没有用的,并且通常 CPPFLAGS
包含预处理器的标志,而不是编译标志,例如 -c
和 -Os
.
我在使用预先在项目中创建的静态库时遇到问题。这个静态库使用 c++11 atomic。一切都编译良好,我的静态库已创建。但是,当我尝试在另一个项目中使用它时,在 link 时出现以下错误:
src/engine/bin/libengine.a(Compound.cpp.o): In function`Job::restart()':
(.text._ZN3Job7restartEv[_ZN3Job7restartEv]+0x30): undefined reference to `__atomic_exchange_1'
其中 Compound.cpp.o 是库的目标文件的时间。 这是我用来创建我的库的 Makefile:
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)/*
有什么想法吗?
您正在编译的目标平台似乎本身不支持 1 字节原子指令,因此您将需要使用提供原子操作作为库函数的 GCC 库。
Link 与 -latomic
到 link 到 GCC 的 libatomic
您的 makefile 尝试这样做,但您只在编译 .o
对象时使用 LFLAGS
,它不会执行任何 linking,因此 -latomic
重要的时候不使用选项。
在编译使用你的静态库的程序时需要使用-latomic
选项,而不是在创建静态库时。
生成文件有点乱。在编译对象时使用 linker 标志是没有用的,并且通常 CPPFLAGS
包含预处理器的标志,而不是编译标志,例如 -c
和 -Os
.