0

我试图将在 Visual Studio 2010 IDE 中编译的工作 C++ 库转换为可在任何标准编译器中编译的通用项目。自从我能够在 Ubuntu 12.10 下使用 Eclipse C++ IDE 进行编译以来,我显然在这个目标上取得了成功。

从那以后,我尝试在终端中使用 g++ 和 Makefile 进行编译。不幸的是,我没有遇到同样的成功。尽管我只收到以下错误,但我似乎非常接近良好的编译:

./liborbit.a(cOrbit.o): In function `Zeptomoby::OrbitTools::cEci::ScalePosVector(double)':
/home/tufts/Programs/workspace/orbitTools/Demo/../core/cEci.h:35: undefined reference to `Zeptomoby::OrbitTools::cVector::Mul(double)'
./liborbit.a(cOrbit.o): In function `Zeptomoby::OrbitTools::cEci::ScaleVelVector(double)':
/home/tufts/Programs/workspace/orbitTools/Demo/../core/cEci.h:36: undefined reference to `Zeptomoby::OrbitTools::cVector::Mul(double)'
./liborbit.a(cNoradBase.o): In function `Zeptomoby::OrbitTools::cNoradBase::FinalPosition(double, double, double, double, double, double, double, double)':
/home/tufts/Programs/workspace/orbitTools/Demo/../orbit/cNoradBase.cpp:265: undefined reference to `Zeptomoby::OrbitTools::cVector::Magnitude() const'
/home/tufts/Programs/workspace/orbitTools/Demo/../orbit/cNoradBase.cpp:285: undefined reference to `Zeptomoby::OrbitTools::cEciTime::cEciTime(Zeptomoby::OrbitTools::cVector const&, Zeptomoby::OrbitTools::cVector const&, Zeptomoby::OrbitTools::cJulian)'
collect2: ld returned 1 exit status
make: *** [compile] Error 1

似乎库函数本身orbit使用库函数。core

文件系统组织:

orbitTools/
├── core
│   ├── cEci.cpp
│   ├── cEci.h
│   ├── cJulian.cpp
│   ├── cJulian.h
│   ├── coord.cpp
│   ├── coord.h
│   ├── coreLib.h
│   ├── cSite.cpp
│   ├── cSite.h
│   ├── cTle.cpp
│   ├── cTle.h
│   ├── cVector.cpp
│   ├── cVector.h
│   ├── exceptions.h
│   ├── globals.cpp
│   ├── globals.h
│   ├── stdafx.cpp
│   └── stdafx.h
├── Demo
│   ├── main.cpp
│   └── Makefile
└── orbit
    ├── cNoradBase.cpp
    ├── cNoradBase.h
    ├── cNoradSDP4.cpp
    ├── cNoradSDP4.h
    ├── cNoradSGP4.cpp
    ├── cNoradSGP4.h
    ├── cOrbit.cpp
    ├── cOrbit.h
    ├── stdafx.cpp
    └── stdafx.h

注意Makefile.

Makefile 本身是:

    # 编译器
    CC = g++

    # 包括文件目录
    主要 = $(PWD)/..
    编译 = $(主)/编译
    核心 = $(主)/核心
    轨道 = $(主)/轨道
    包括 = -I$(主)-I$(核心)-I$(轨道)-I。

    # 发展选项
    CFLAGS = -g -ansi

    编译:main.o 库
        $(CC) $(INCLUDE) $(CFLAGS) main.o -L。-lcore -lorbit -lm -o 演示

    主.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c main.cpp

    # 核心库
    cEci.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(CORE)/cEci.cpp

    cJulian.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(CORE)/cJulian.cpp

    坐标.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(CORE)/coord.cpp

    cSite.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(CORE)/cSite.cpp

    cTle.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(CORE)/cTle.cpp

    cVector.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(CORE)/cVector.cpp

    全局变量.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(CORE)/globals.cpp

    stdafx.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(CORE)/stdafx.cpp

    核心:cEci.o cJulian.o coord.o cSite.o cTle.o cVector.o globals.o stdafx.o
        ar rcs libcore.a cEci.o cJulian.o coord.o cSite.o cTle.o cVector.o globals.o stdafx.o

    # 轨道图书馆
    cNoradBase.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(ORBIT)/cNoradBase.cpp -lcore

    cNoradSDP4.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(ORBIT)/cNoradSDP4.cpp -lcore

    cNoradSGP4.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(ORBIT)/cNoradSGP4.cpp -lcore

    cOrbit.o:
        $(CC) $(INCLUDE) $(CFLAGS) -c $(ORBIT)/cOrbit.cpp -lcore

    轨道:cNoradBase.o cNoradSDP4.o cNoradSGP4.o cOrbit.o stdafx.o
        ar rcs liborbit.a cNoradBase.o cNoradSDP4.o cNoradSGP4.o cOrbit.o stdafx.o

    库:核心轨道

    干净的:
        rm *.o

    清除:
        rm *.a
4

1 回答 1

2

如果orbit使用core,则-lorbit 必须前面 -lcore

如果core还使用orbit(循环依赖),那么你需要做类似的事情-lorbit -lcore -lorbit(列出其中一个两次)。

说明:

GNU 链接器(与大多数 UNIX 链接器一样)是“单通道链接器”。这意味着它从您的目标文件开始并记录任何未解析的符号。然后它查看链接行上的第一个库,并拉入任何可以满足一个或多个未解析符号的对象。同时,它会添加被它拉入的那些对象引用的任何新的未解析符号。然后它会转到链接行上的下一个库。等等。

如果它通过链接行上的所有库并且仍然存在未解析的符号,则链接失败。

因此,您需要订购您的库,以便不依赖任何其他内容的最基本的库位于最后g++前端会自动在末尾添加C-lc运行时库——显然这是 MOST 基础库。除了基本库之外不依赖任何东西的库就在这些库之前。等等。

于 2013-04-09T18:08:37.923 回答