我正在嘗試使用Boost :: Test爲庫創建C庫和C++測試程序。我在這個問題中發佈的代碼是對我的代碼的簡化,它顯示了完全相同的問題。請幫忙!與靜態庫鏈接時未定義的引用,但與src編譯時成功鏈接
這是目錄結構。 childlib
是我正在創建的庫,test
是測試程序。
> tree
.
`-- src
|-- main
| |-- c
| | `-- childlib.c
| |-- childlib.h
| `-- makefile
`-- test
|-- cpp
| `-- test.cpp
`-- makefile
5 directories, 5 files
我可以讓childlib
成爲一個成功的靜態庫:
> cd src/main
> make
gcc -c -fPIC -o c/childlib.o c/childlib.c
ar rcs libchildlib.a c/childlib.o
ranlib libchildlib.a
但我不能用它連接使我的測試程序:
> cd ../test/
> make
g++ -I. -I../main -Imy_boost_install_dir/include -c -std=c++11 -o cpp/test.o cpp/test.cpp
g++ -L../main -Lmy_boost_install_dir/lib -lchildlib -lboost_unit_test_framework -Wl,-rpath=my_boost_install_dir/lib -o test_childlib cpp/test.o
cpp/test.o: In function `test_func1::test_method()':
test.cpp:(.text+0x15e7e): undefined reference to `childlib_func1()'
collect2: error: ld returned 1 exit status
make: *** [test_childlib] Error 1
。另一方面,如果我通過刪除對靜態庫的引用並將childlib.c添加爲源文件來手動運行編譯,我可以成功完成測試程序:
> g++ -Lmy_boost_install_dir/lib -lboost_unit_test_framework -Wl,-rpath=my_boost_install_dir/lib -o test_childlib cpp/test.o ../main/c/childlib.c
> ./test_childlib
Running 1 test case...
*** No errors detected
下面是各種源文件。 TEST.CPP:
#include <cstdlib>
#include <stdint.h>
#define BOOST_TEST_MODULE childlib test
#include <boost/test/unit_test.hpp>
#include <boost/test/included/unit_test.hpp>
#include "childlib.h"
BOOST_AUTO_TEST_CASE(test_func1) {
childlib_func1();
BOOST_CHECK(true);
}
childlib.h:
#ifndef CHILDLIB_H_
#define CHILDLIB_H_
void childlib_func1();
#endif /* CHILDLIB_H_ */
終於childlib.c:
#include <stdint.h>
void childlib_func1() {
return;
}
兩個makefile文件如下。
childlib
生成文件:最後,我也想創建一個動態庫,但現在它註釋掉的make all
:
# childlib
CC = gcc
SRCS = $(wildcard c/*.c)
OBJS = $(SRCS:.c=.o)
HDRS = $(wildcard *.h)
MODULE_BASE_NAME = childlib
MODULE_LIB_A = lib$(MODULE_BASE_NAME).a
MODULE_LIB_SO = lib$(MODULE_BASE_NAME).so
INCLUDE_DIRS = .
INCLUDE = $(addprefix -I,$(INCLUDE_DIRS))
CFLAGS = -c -fPIC
all: $(MODULE_LIB_A) # $(MODULE_LIB_SO)
$(MODULE_LIB_A): $(OBJS)
ar rcs [email protected] $^
ranlib [email protected]
$(MODULE_LIB_SO): $(OBJS)
$(CC) -shared -o [email protected] $^
.c.o:
$(CC) $(CFLAGS) -o [email protected] $^
clean:
-rm -f $(MODULE_LIB_A) $(MODULE_LIB_SO) $(OBJS)
-find . -name '*~' -delete
這裏的測試工具生成文件:
# test
CC = g++
SRCS = $(wildcard cpp/*.cpp)
OBJS = $(SRCS:.cpp=.o)
MODULE_EXE = test_childlib
MAIN_DIR = ../main
BOOST_DIR = my_boost_install_dir
BOOST_INC_DIR = $(BOOST_DIR)/include
BOOST_LIB_DIR = $(BOOST_DIR)/lib
BOOST_LIBS = boost_unit_test_framework
INCLUDE = $(addprefix -I,. $(MAIN_DIR) $(BOOST_INC_DIR))
LIB_DIRS = $(addprefix -L,$(MAIN_DIR) $(BOOST_LIB_DIR))
LIBS = $(addprefix -l,childlib $(BOOST_LIBS))
LINKER_OPTS = -Wl,-rpath=$(BOOST_LIB_DIR)
CFLAGS = -c -std=c++11
all: test
test: $(MODULE_EXE)
./$(MODULE_EXE)
$(MODULE_EXE): $(OBJS)
$(CC) $(LIB_DIRS) $(LIBS) $(LINKER_OPTS) -o [email protected] $^
.cpp.o:
$(CC) $(INCLUDE) $(CFLAGS) -o [email protected] $^
clean:
-rm -f $(MODULE_EXE) $(OBJS)
-find . -name '*~' -delete
我用gcc & g ++ 4.8.1。我也使用gcc 4.7.2編譯的boost 1.54.0。
看來我需要在測試makefile中爲g ++提供正確的選項,但我不知道它們是什麼。有人可以幫我連接childlib
庫和我的測試程序嗎?
'-fPIC'標誌將與__shared__庫一起使用,而不是靜態的。 – Chnossos
@Chnossos - 我試圖從childlib makefile中刪除-fPIC,然後清理/重建這兩個模塊。使測試裝置以同樣的方式失敗。 –
我將childlib的編譯器更改爲g ++而不是gcc,並且我可以鏈接到測試工具!我仍然想將childlib編譯爲C庫而不是C++,但也許這有助於指出答案。我將開始研究如何將C庫與C++ exe鏈接起來。 –