build failed when link mongo c++ driver

這幾天忙著升級到maverick
xcode也升級到5.0
然後開始將之前寫的server程式重新編譯
之前用了一些library都順利轉到新的os上了
包含poco library、boost、mysql、thrift等等
唯獨一個mongo c++ driver老是失敗
後來加上c++11的參數後也順利編譯成功
只是在link的時候老是出現以下錯誤

  Undefined symbols for architecture x86_64:
  "mongo::Status::~Status()", referenced from:
      mongo::BSONArrayBuilder::fill(mongo::StringData const&) in icService.o
  ld: symbol(s) not found for architecture x86_64
  clang: error: linker command failed with exit code 1 (use -v to see invocation)

這到底是什麼問題,重新編譯了幾次,換了無數的參數還是一樣,最後我懷疑是編譯器相容性的問題
於是我只好去翻一下source code,把Status::~Status()給找出來,在base底下發現了這支程式

namespace mongo {

    /**
     * Status represents an error state or the absence thereof.
     *
     * A Status uses the standardized error codes -- from file 'error_codes.h' -- to
     * determine an error's cause. It further clarifies the error with a textual
     * description. Optionally, a Status may also have an error location number, which
     * should be a unique, grep-able point in the code base (including assert numbers).
     *
     * Example usage:
     *
     *    Status sumAB(int a, int b, int* c) {
     *       if (overflowIfSum(a,b)) {
     *           return Status(ErrorCodes::ERROR_OVERFLOW, "overflow in sumAB", 16494);
     *       }
     *
     *       *c = a+b;
     *       return Status::OK();
     *   }
     *
     * TODO: expand base/error_codes.h to capture common errors in current code
     * TODO: generate base/error_codes.h out of a description file
     * TODO: check 'location' duplicates against assert numbers
     */
    class MONGO_CLIENT_API Status {
    public:
        // Short-hand for returning an OK status.
        static inline Status OK();

        /**
         * Builds an error status given the error code, a textual description of what
         * caused the error, and a unique position in the where the error occurred
         * (similar to an assert number)
         */
        Status(ErrorCodes::Error code, const std::string& reason, int location = 0);
        Status(ErrorCodes::Error code, const char* reason, int location = 0);

          inline Status(const Status& other);
        inline Status& operator=(const Status& other);
        inline ~Status();


        /**
         * Returns true if 'other's error code and location are equal/different to this
         * instance's. Otherwise returns false.
         */
        bool compare(const Status& other) const;
        bool operator==(const Status& other) const;
        bool operator!=(const Status& other) const;

        /**
         * Returns true if 'other's error code is equal/different to this instance's.
         * Otherwise returns false.
         */
        bool compareCode(const ErrorCodes::Error other) const;
        bool operator==(const ErrorCodes::Error other) const;
        bool operator!=(const ErrorCodes::Error other) const;

        //
        // accessors
        //

         inline bool isOK() const;

         inline ErrorCodes::Error code() const;

         inline std::string codeString() const;

         inline std::string reason() const;

         inline int location() const;

        std::string toString() const;

        //
        // Below interface used for testing code only.
        //

         inline AtomicUInt32::WordType refCount() const;

    private:
         inline Status();

        struct ErrorInfo {
            AtomicUInt32 refs;             // reference counter
            const ErrorCodes::Error code;  // error code
            const std::string reason;      // description of error cause
            const int location;            // unique location of the triggering line in the code

            static ErrorInfo* create(ErrorCodes::Error code,
                                     const StringData& reason, int location);

            ErrorInfo(ErrorCodes::Error code, const StringData& reason, int location);
        };

        ErrorInfo* _error;

        /**
         * Increment/Decrement the reference counter inside an ErrorInfo
         *
         * @param error  ErrorInfo to be incremented
         */
        static inline void ref(ErrorInfo* error);
        static inline void unref(ErrorInfo* error);
    };

    MONGO_CLIENT_API inline bool operator==(const ErrorCodes::Error lhs, const Status& rhs);

    MONGO_CLIENT_API inline bool operator!=(const ErrorCodes::Error lhs, const Status& rhs);

    //
    // Convenience method for unittest code. Please use accessors otherwise.
    //

    MONGO_CLIENT_API std::ostream& operator<<(std::ostream& os, const Status& status);
    MONGO_CLIENT_API std::ostream& operator<<(std::ostream& os, ErrorCodes::Error);

}  // namespace mongo

#include "mongo/base/status-inl.h"

我想大概是inline這個東西卡到陰了,所以迅速將所有的inline全部幹掉,重新編譯後再link就解掉這個問題了
為了到達這一步足足搞了好幾天,損失數十個小時的工作效能
不過也很慶幸,還好mongodb是open source的,不然不就準備放生了嗎?