CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Jan 2011
    Posts
    3

    Can't compile; two source files

    I'm learning c++ from a guidebook, and one of the exercises has me build and run a project with two source files. I'm using Code::Blocks on mac 10.6. When I try to build and run, it says there are no errors, but doesn't run.

    The first (main.cpp) is:
    Code:
    #include <iostream>
    
    using namespace std;
    
    void ProgRun(int choice);
    
    int main()
    {
        ProgRun(3);
        return 0;
    }
    The second (othersource.cpp) is:
    Code:
    #include <iostream>
    
    using namespace std;
    
    void ProgRun(int choice)
    {
        cout << "You chose: " << choice << endl;
    }
    I click build and run (F9), and a dialog pops up, saying "This project has not yet been built," (what!?) "Do you want to build it?"
    I click yes, and nothing happens. The build log says this:

    -------------- Build: Debug in MultipleSource ---------------

    Linking console executable: bin/Debug/MultipleSource
    Undefined symbols:
    "ProgRun(int)", referenced from:
    _main in main.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status
    Process terminated with status 1 (0 minutes, 0 seconds)
    0 errors, 0 warnings

    Not sure if this is a Code::Blocks issue or not (the mac build is apparently more buggy), but their message board specifically says not to ask questions about errors during build time, so I thought it best to ask here.
    (Kind of reminds me of when I had problems running xp on my mac mini; Apple wouldn't help me because it was Microsoft software, and Microsoft wouldn't help me because it was Apple hardware.)

    I googled the problem as any good person would and found many results, but I'm just fresh into the c++ world, and I couldn't understand anything I found. A little help in "beginner" language would be appreciated.

    Thanks in advance.

  2. #2
    Join Date
    Aug 2009
    Posts
    440

    Re: Can't compile; two source files

    The main problem is that you have not told main.cpp where to look for the function ProgRun. You've only declared it, but you haven't defined it. You would need to include the other file in main to tell it where to find that function (I'd probably just remove the:
    Code:
    void ProgRun(int choice);
    line from main. In addition you typically include header files, not .cpp files. So, what you could do is create a header file for othersource.cpp and just put the function declaration there. Then you'd include that header file in both .cpp files.
    Last edited by Alterah; January 7th, 2011 at 01:03 AM.

  3. #3
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Can't compile; two source files

    Quote Originally Posted by Alterah View Post
    ...
    Including files only tells the compiler the signature of functions so it can generate compiled code, even if it doesn't know the definition. It is the linker that then looks for the implementation, and it does not need includes.

    Your recommendations are correct, but the OP's code IS well built, and should run perfectly fine.

    Did you make ProgRun.cpp an actual file in your project? The file is probably open in your editor, but did you add it to the project? Your log is leading me to think that it is being ignored, hence the link error.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  4. #4
    Join Date
    Jan 2011
    Posts
    3

    Re: Can't compile; two source files

    @Alterah:
    In the guidebook, it shows how to make header files in the following exercise, so I assumed it would work fine without one. Just to be on the safe side, however, I skipped ahead and made a header file, linking it in both .cpp files. The result was exactly the same.

    @monarch_dodra:
    I checked in the folder, and the file does actually exist.

    Just on a lark, I tried the exact same project on Code::Blocks under Windows 7. It worked perfectly. Clearly, a Code::Blocks issue. As for what the issue is, I don't really care right now, I just want to get back to learning. Thanks for the help anyway, though.

  5. #5
    Join Date
    Aug 2008
    Posts
    902

    Re: Can't compile; two source files

    No, it's not a Code::Blocks issue, it's a compiler/linker (gcc/ld) error.

  6. #6
    Join Date
    Apr 2008
    Posts
    118

    Re: Can't compile; two source files

    The error means that the linker cannot find the actual compiled function to run. You did not include the object file in your build. At risk of sounding harsh, it's not a Code::Blocks problem, it's a you not understanding what the linker is for and how to work it problem.

    There's no shame in not understanding how something works, and now that you know what you don't understand here you can do something about it.

  7. #7
    Join Date
    Jan 2011
    Posts
    3

    Re: Can't compile; two source files

    Quote Originally Posted by Moschops View Post
    There's no shame in not understanding how something works, and now that you know what you don't understand here you can do something about it.
    Care to share what exactly it is that I should do? Am I missing a file or something?

  8. #8
    Join Date
    Apr 2008
    Posts
    118

    Re: Can't compile; two source files

    No, you're not missing any files.

    Here's how it works. The preprocessor runs and in every file swaps

    "#include someFile"

    with the entire contents of someFile.

    Then, each resulting file is compiled into object code, by the compiler. This will create a number of new files; object files.

    Then, each object file is linked into the built executable or library, by the linker.

    This is what enables you to call ProgRun; the actual machine code for that is in the object file built from othersource.cpp. To use ProgRun the linker must link in an object file containing this code. It is complaining that it can't find an object file containing this function. You will need to examine your tools and discover how to specify what files should be linked to, and double check that you are building the object file.

    For example, if you were doing this with the ubiquitous gcc, your command line would be something like:

    g++ main.cpp othersource.cpp

    This works perfectly with the two files you gave in your original post. I can also do it this way, which demonstrates the complete build chain, and I also included the same error you must have made to get the error regards undefined ProgRun. The commands I typed are in bold.

    Code:
    j@j-desktop:~/temp/temp01$ l
    total 8
    -rw-r--r-- 1 j j 116 2011-01-09 02:28 main.cpp
    -rw-r--r-- 1 j j 118 2011-01-09 02:26 otherSource.cpp
    j@j-desktop:~/temp/temp01$ g++ -c main.cpp otherSource.cpp 
    j@j-desktop:~/temp/temp01$ l
    total 16
    -rw-r--r-- 1 j j  116 2011-01-09 02:28 main.cpp
    -rw-r--r-- 1 j j 2288 2011-01-09 02:30 main.o
    -rw-r--r-- 1 j j  118 2011-01-09 02:26 otherSource.cpp
    -rw-r--r-- 1 j j 2800 2011-01-09 02:30 otherSource.o
    j@j-desktop:~/temp/temp01$ g++ main.o -o theOutputExecutable
    main.o: In function `main':
    main.cpp:(.text+0xa): undefined reference to `ProgRun(int)'
    collect2: ld returned 1 exit status
    j@j-desktop:~/temp/temp01$ g++ main.o otherSource.o -o theOutputExecutable
    j@j-desktop:~/temp/temp01$ l
    total 28
    -rw-r--r-- 1 j j  116 2011-01-09 02:28 main.cpp
    -rw-r--r-- 1 j j 2288 2011-01-09 02:30 main.o
    -rw-r--r-- 1 j j  118 2011-01-09 02:26 otherSource.cpp
    -rw-r--r-- 1 j j 2800 2011-01-09 02:30 otherSource.o
    -rwxr-xr-x 1 j j 9368 2011-01-09 02:31 theOutputExecutable*
    j@j-desktop:~/temp/temp01$ ./theOutputExecutable 
    You chose: 3
    You can see there that I start with the two cpp files, then I compile them both into object files, then I ask the linker to build me an executable; I did it using g++ both times, because there are a large number of standard libraries that I didn't want to have to specify by hand. The only objects I did have to specify by hand were the two I'd made myself.

    To give an idea of what's going on behind the scenes when the linker does it's job, here's the path and standard library details that get used every time I run a build:

    Code:
    COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.4.3/:/usr/lib/gcc/x86_64-linux-gnu/4.4.3/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.4.3/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.4.3/:/usr/lib/gcc/x86_64-linux-gnu/
    LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.4.3/:/usr/lib/gcc/x86_64-linux-gnu/4.4.3/:/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../:/lib/:/usr/lib/:/usr/lib/x86_64-linux-gnu/
    COLLECT_GCC_OPTIONS='-v' '-o' 'theOutputExecutable' '-shared-libgcc' '-mtune=generic'
     /usr/lib/gcc/x86_64-linux-gnu/4.4.3/collect2 --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o theOutputExecutable -z relro /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.4.3/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.4.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../.. -L/usr/lib/x86_64-linux-gnu main.o otherSource.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.4.3/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crtn.o
    An awful lot of extra libraries being linked to there!

  9. #9
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Can't compile; two source files

    Quote Originally Posted by code:9999 View Post
    I checked in the folder, and the file does actually exist.
    That's what I told you, it does not matter if the file actually exits, if you don't tell your compiler to compile it. By adding the file to the project, it will be correctly compiled, and you won't have link problems.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured