首页 > 解决方案 > Makefile:架构 x86_64 的未定义符号

问题描述

我正在使我的应用程序更便于在其他操作系统上运行。适用于 XCode 和 Visual Studio。但是,切换到 Makefiles 给我带来了一些问题。

错误:

Undefined symbols for architecture x86_64:                                     
"AppObject::Instance()", referenced from:                        
  _main in main-329f6c.o                                                                                          
ld: symbol(s) not found for architecture x86_64

主文件

#include <iostream>

#include "AppObject.hpp"

AppObject* _appObject;

int main()
{
    _appObject = AppObject::Instance();

    return 0;
}

应用对象.hpp

#ifndef  _APPOBJECT_HPP_
#define  _APPOBJECT_HPP_

#include <iostream>

class AppObject
{
    public:
        static AppObject* Instance();
        virtual ~AppObject() {}

        void initInstance();

    private:
        AppObject();
        AppObject(const AppObject&);
        AppObject& operator= (const AppObject&);
        static AppObject* pinstance; 
};

#endif // _APPOBJECT_HPP_

应用对象.cpp

#include "AppObject.hpp"

AppObject* AppObject::pinstance = 0;

AppObject::AppObject() {}

AppObject* AppObject::Instance()
{
    if (pinstance == 0)
    {
        pinstance = new AppObject;
        pinstance->initInstance();
    }

    return pinstance;
}

void AppObject::initInstance()
{
   .....
}

这有点配对,但我也看到了一些其他警告:

warning: in-class initialization of non-static data member is a C++11 extension

谁能帮我理解我的错误,我的这在 XCode 和 VS 中有效,但不使用 make?

生成文件

CXX=clang++
CXXFLAGS=-g -std=c++11 -Wall -pedantic -c

LDFLAGS=-L/usr/local/opt/sqlite/lib
CPPFLAGS=-I/usr/local/opt/sqlite/include

SOURCES=scraper/main.cpp scraper/AppObject.cpp scraper/SQLManager.cpp

OBJECTS=$(SOURCES:.cpp=.o)

EXECUTABLE=scraper

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS) 
    $(CXX) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
    $(CXX) $(CXXFLAGS) $< -o $@

完整的输出:

$ make
clang  scraper/main.cpp -o scraper/main.o
In file included from scraper/main.cpp:3:
In file included from scraper/AppObject.hpp:6:
scraper/SQLManager.hpp:44:30: warning: in-class initialization of non-    static data member is a C++11 extension
  [-Wc++11-extensions]
        bool _bDatabaseReady = false;
                         ^
scraper/SQLManager.hpp:46:29: warning: in-class initialization of non-    static data member is a C++11 extension
  [-Wc++11-extensions]
        std::string _dbFile = "popcorn.db3";
                        ^
scraper/SQLManager.hpp:47:29: warning: in-class initialization of non-    static data member is a C++11 extension
  [-Wc++11-extensions]
        std::string _dbName = "popcorn";
                        ^
scraper/SQLManager.hpp:49:24: warning: in-class initialization of non-    static data member is a C++11 extension
      [-Wc++11-extensions]
        int _dbVersion = 1; // increment this when database structure changes
                   ^
scraper/SQLManager.hpp:51:28: warning: in-class initialization of non-static data member is a C++11 extension
      [-Wc++11-extensions]
        int _dbVersionType = 0; // 0 = normal, 1 = free, 2 = lite
                       ^
5 warnings generated.
Undefined symbols for architecture x86_64:
  "AppObject::Instance()", referenced from:
      _main in main-4a5276.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see     invocation)
make: *** [scraper/main.o] Error 1

make从回复中获取建议后更新输出:

$ make
clang++  scraper/main.cpp -o scraper/main.o
In file included from scraper/main.cpp:3:
In file included from scraper/AppObject.hpp:6:
scraper/SQLManager.hpp:44:30: warning: in-class initialization of non-    static data member is a C++11 extension [-Wc++11-extensions]
        bool _bDatabaseReady = false;
                         ^
scraper/SQLManager.hpp:46:29: warning: in-class initialization of non-    static data member is a C++11 extension [-Wc++11-extensions]
        std::string _dbFile = "popcorn.db3";
                        ^
scraper/SQLManager.hpp:47:29: warning: in-class initialization of non-    static data member is a C++11 extension [-Wc++11-extensions]
        std::string _dbName = "popcorn";
                        ^
scraper/SQLManager.hpp:49:24: warning: in-class initialization of non-    static data member is a C++11 extension [-Wc++11-extensions]
        int _dbVersion = 1; // increment this when database structure changes
                   ^
scraper/SQLManager.hpp:51:28: warning: in-class initialization of non-    static data member is a C++11 extension [-Wc++11-extensions]
        int _dbVersionType = 0; // 0 = normal, 1 = free, 2 = lite
                       ^
5 warnings generated.
Undefined symbols for architecture x86_64:
  "AppObject::Instance()", referenced from:
      _main in main-0e97bb.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see     invocation)
make: *** [scraper/main.o] Error 1

标签: c++makefilecompiler-errors

解决方案


首先clangC前端。虽然它可用于编译 C++ 代码,但它不会添加 C++ 所需的所有头文件路径或链接器库。使用clang++.

其次,您显示的输出根本没有任何标志。

第三,链接器错误的原因是您没有使用-c创建目标文件所需的标志。如果没有该-c标志,您将告诉前端clang程序构建并链接一个名为scraper/main.o.


推荐阅读