c++ - 编译错误(g++ 和 make)

标签 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

最佳答案

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

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

说明:

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

如果它遍历了链接线上的所有库,但仍有未解析的符号,则链接失败。

因此,您需要对库进行排序,以便不依赖于任何其他任何内容的最基本的库位于末尾g++ 前端会自动在最后添加-lc,即C 运行时库——显然这是最基本的库。除了基本库之外什么都不依赖的库就在它们之前。等等

关于c++ - 编译错误(g++ 和 make),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15909039/

相关文章:

c++ - 如何验证 LLVM "ret"指令是否返回无效?

c++ - header 包含 std c++ 库后的 undefined symbol

c++ - ftp 服务器的 makefile - 修改头文件时编译

c - 如何链接来自不同目录的对象(运行 ld)

c++ - 无法使用 execlp() 和字符串中的命令执行二进制文件

c++ - 可以在 Microsoft Visual C++ 2010 Express Edition 中安装 Whole Tomatoes Visual Assist X 吗?

c++ - 为 C++ 配置 google glog 和 gflags

c - 在路径中找不到程序 g++

c++11 有时会包含 <cstdlib> 而 c++03 不会?

c++ - 使文件问题 : always spits out "Nothing to be done for ` make. w'。”