编译错误(g ++和make)

时间:2013-04-09 17:51:49

标签: c++ g++ makefile

我试图将在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本身是:


    # COMPILER
    CC = g++

    # INCLUDE FILES DIRECTORY
    MAIND = $(PWD)/..
    COMPILE = $(MAIND)/compile
    CORE = $(MAIND)/core
    ORBIT = $(MAIND)/orbit
    INCLUDE = -I$(MAIND) -I$(CORE) -I$(ORBIT) -I.

    # OPTIONS FOR DEVELOPMENT
    CFLAGS = -g -ansi

    compile: main.o libs
        $(CC) $(INCLUDE) $(CFLAGS) main.o -L. -lcore -lorbit -lm -o demo

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

    # CORE LIBRARY
    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

    core: 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

    # ORBIT LIBRARY
    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

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

    libs: core orbit

    clean:
        rm *.o

    purge:
        rm *.a

1 个答案:

答案 0 :(得分:2)

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

如果core也使用orbit(周期性依赖),那么您需要执行-lorbit -lcore -lorbit之类的操作(将其中一个列出两次)。

阐释:

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

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

因此,您需要订购您的库,以便最基本的库不依赖于任何其他库,位于 end g++前端会在结尾处自动添加-lc C运行时库 - 显然这是MOST基本库。除了基本库之外什么都不依赖的库就在它们之前。等