Search code examples
c++makefile

How to solve error: /usr/bin/ld: cannot find main: No such file or directory


I am trying to create a makefile to run a simple C++ application in VS code, but I am getting a Linker error when it tries to execute the target to create the executable file:

/usr/bin/ld: cannot find main: No such file or directory
/usr/bin/ld: main.o: _ZSt4cout: invalid version 2 (max 0)
/usr/bin/ld: main.o: error adding symbols: bad value
collect2: error: ld returned 1 exit status
make: *** [makefile:5: main] Error 1

I searched for posts related to the /usr/bin/ld: message, but they all seemed to be linked to problems having to with connecting to external shared library files.

M application, on the other hand, uses no external libraries but instead keeps all of the files, including the object(.o) files and final executable, in the same directory.

Here is the makefile code:

CXX = g++ 
CXXFLAGS = -Wall -Wextra -pedantic

main: main.o Movies.o Movie.o
    $(CXX) $(CXXFLAGS) $@ $^

main.o: main.cpp Movies.cpp Movie.cpp
    $(CXX) $(CXXFLAGS) -o $@ $^

Movie.o: Movie.cpp Movie.h
    $(CXX) $(CXXFLAGS) -c -o $@ $^

Movies.o: Movies.cpp Movies.h
    $(CXX) $(CXXFLAGS) -c -o $@ $^

run:
    ./main

clean:
    rm -rf *.o main

UPDATE: I should add that I am fairly new to C++ and makefiles in general. My original intent was to build up the makefile by creating the individual targets for each of my source files as a means of practicing and learning.

The Movies.cpp class is nothing more than a container class to hold a collection of Movie.cpp objects, more specifically a vector for Movie objects. The actual main.cpp file only includes the Movies.h header in its main() function.

I hope this extra information helps.


Solution

  • main.o rule command $(CXX) $(CXXFLAGS) -o $@ $^ w/o -c does not build an object file, it builds ./main.o executable. Compare it with other rules. main rule command links with main.o executable and the command fails.

    This is all what you need

    CXX = g++ 
    CXXFLAGS = -Wall -Wextra -pedantic
    
    main: main.cpp Movies.cpp Movie.cpp
        $(CXX) $(CXXFLAGS) -o $@ $^
    
    run: main
        ./main
    
    clean:
        rm -f main
    

    Or fix the rule main.o and command sources

    XX = g++ 
    CXXFLAGS = -Wall -Wextra -pedantic
    
    main: main.o Movies.o Movie.o
        $(CXX) $(CXXFLAGS) $@ $^
    
    main.o: main.cpp Movie.h Movies.h
        $(CXX) $(CXXFLAGS) -c -o $@ $<
    
    Movie.o: Movie.cpp Movie.h
        $(CXX) $(CXXFLAGS) -c -o $@ $<
    
    Movies.o: Movies.cpp Movies.h
        $(CXX) $(CXXFLAGS) -c -o $@ $<
    
    run: main
        ./main
    
    clean:
        rm -rf *.o main