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)/..
    COMPILE = $(MAIND)/コンパイル
    コア = $(MAIND)/コア
    ORBIT = $(MAIND)/軌道
    INCLUDE = -I$(メイン) -I$(コア) -I$(オービット) -I.

    # 開発オプション
    CFLAGS = -g -ansi

    コンパイル: main.o ライブラリ
        $(CC) $(INCLUDE) $(CFLAGS) main.o -L. -lcore -lorbit -lm -o デモ

    main.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

    coord.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

    globals.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(そのうちの 1 つを 2 回リストします)。

解明:

GNU リンカ (ほとんどの UNIX リンカと同様) は「シングル パス リンカ」です。これは、オブジェクト ファイルから開始し、未解決のシンボルをすべて記録することを意味します。次に、リンク行の最初のライブラリを調べて、それらの未解決のシンボルの 1 つ以上を満たすことができるオブジェクトを取り込みます。同時に、引き込んだオブジェクトによって参照された、新しく未解決のシンボルを追加します。次に、リンク行の次のライブラリに移動します。等。

リンク ライン上のすべてのライブラリを通過しても、まだ未解決のシンボルがある場合、リンクは失敗します。

そのため、他のものに依存しない最も基本的なライブラリが最後になるように、ライブラリを並べ替える必要があります。g++フロントエンドは、C ランタイム ライブラリである を最後に自動的に追加します。これ-lcは明らかに、最も基本的なライブラリです。基本ライブラリ以外に依存しないライブラリは、それらの直前に置かれます。等。

于 2013-04-09T18:08:37.923 に答える