Search code examples
c++xcode4.5

Xcode Apple Mach-O linker (ld) error


Hi I am trying to follow the stanford cs106/x course but they use certain libraries that they no longer provide. I have managed to find a version of them but I constantly get an error. I added the .h files to the current project I was using them in. This is the simple code im running in C++:

#include <iostream>
#include "genlib.h"
#include "simpio.h"


int main()
{
    cout << "How much do you love me? ";
    int howAweSome = GetInteger();
    for (int i = 0; i < howAweSome; i++)
    cout << "10GB rocks!" << endl;
    return 0;
}

The following errors occur:

Undefined symbols for architecture x86_64:
"GetInteger()", referenced from:
  Main() in main.o
"_main", referenced from:
 -u command line option
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Here are the libraries used:

"simplio.h":

/*
* File: simpio.h
* Last modified on Wed Jul 22 07:01:03 2009 by eroberts
*      modified on Wed Sep 18 13:34:29 2002 by zelenski
* -----------------------------------------------------
* This interface provides access to a simple package of
* functions that simplify the reading of console input.
*/

#ifndef _simpio_h
#define _simpio_h

#include "genlib.h"

/*
* Function: GetInteger
* Usage: n = GetInteger();
* ------------------------
* GetInteger reads a line of text from standard input and scans
* it as an integer.  The integer value is returned.  If an
* integer cannot be scanned or if more characters follow the
* number, the user is given a chance to retry.
*/

int GetInteger();

/*
* Function: GetLong
* Usage: n = GetLong();
* ---------------------
* GetLong reads a line of text from standard input and scans
* it into a long integer.  The long is returned.  If the
* number cannot be scanned or if extra characters follow it,
* the user is given a chance to retry.
*/

long GetLong();

/*
* Function: GetReal
* Usage: x = GetReal();
* ---------------------
* GetReal reads a line of text from standard input and scans
* it as a double.  If the number cannot be scanned or if extra
* characters follow after the number ends, the user is given
* a chance to reenter the value.
*/

double GetReal();

/*
* Function: GetLine
* Usage: s = GetLine();
* ---------------------
* GetLine reads a line of text from standard input and returns
* the line as a string.  The newline character that terminates
* the input is not stored as part of the string that is returned.
*/

string GetLine();

#endif

The "genlib.h":

/*
 * File: genlib.h
 * Last modified on Sun Jul 17 2011 by Colin Leach
 *      modified on Mon Jun  8 20:16:05 2009 by eroberts
 *      modified on Wed Sep 18 13:41:31 2002 by zelenski
 * -----------------------------------------------------
 * This header file is indicated to be included in
 * all the programs written for CS106B/X and provides a few
 * common definitions. Note this header has a "using namespace std"
 * clause. If a file includes this header, it can then use
 * features from the std namespace without qualifying by scope.
 *
 * IMPORTANT!!  I had to change the interface after failing to
 * implement the Stanford version. Hence the genlib.h bundled
 * with CS106B exercises is NOT compatible - don't use it with 
 * Colin's open-source library code.
 * Apologies for the inconvenience, but I'm a C++ novice doing
 * the best I can.
 */

 #ifndef _genlib_h
 #define _genlib_h

 /* This strange-looking pragma is here to disable a warning from Visual C++
 * about truncating long identifiers for debugging symbols. The warning is
 * harmless, but a little disconcerting, so we suppress it. It comes up
 * using STL and other long template expansions.
 */
 #if defined(_MSC_VER)
 #pragma warning(disable: 4786)
 #endif

 #include <string>
 #include <exception>
 using namespace std;

 /*
 * Class: ErrorException
 * ---------------------
 * This exception is raised by calls to the Error function, which
 * makes it possible for clients to respond to error conditions
 * without having their programs bomb completely.
 */

 class ErrorException : public exception {
 public:
    ErrorException(string msg);
     virtual ~ErrorException() throw ();
     virtual const char* what() const throw ();
     //virtual string getMessage();
 private:
  string msg;
 };

/*
* Function: Error
* Usage: Error(msg);
* ------------------
* Error is used to signal an error condition in a program.  It first
* throws an ErrorException.  If that isn't caught, it outputs the
* error message string to the cerr stream and then exits the program
* with a status code indicating failure.
*/

void Error(string str);

/*
* Function macro: main
* --------------------
* The purpose of this macro definition is to rename the student
* main to Main in order to allow a custom main defined in our
* libraries to configure the application before passing control
* back to the student program.
*
* Note that this non-Stanford version only affects the zero-argument
* form of main(), not main(int argc, char* argv[]).
* If you want to use command-line arguments, you also have to catch
* your own ErrorException - see init.h/init.cpp for details.
*/

 #define main() Main()

 #endif

I am running Xcode 4.5.2 on a macbook pro OS X 10.8.2. If anyone knows how to resolve the problem it would be of great help.


Solution

  • The .h files only declare that certain functions exist. To link your program with them, you need to have actual implementations of those functions.

    For each of the .h files, there should be a matching .c or .cpp that you would include in your build. (Or, if it were distributed as binary, .a or .dylib.)