I'm trying to run a c program on an external computer running Linux, but I have problems with compiling. The program compiles fine in Visual Studio Code on my personal Mac...
My knowledge of programming and computer is somewhat limited, but I believe the computer uses a GNU compiler, and after some googling. At least it uses something different than VS Code on my mac, as I had to alter the Makefile.
When I use the command "make" to build my program (which consists of several .h and .cpp files), I get some errors that I don't know how to resolve, but I assume it has something to do with my two classes "Subproblem" and "Label" (see the bottom of this post for error code)
Both classes have member functions that take the other in as an argument. Thus I've used a forward declaration of the Subproblem-class before the definition of my Label-class. Here's a simplified version of my code in Label.h, including the functions that are referenced in the error message:
#pragma once
#include "Duals.h"
#include "Nodes.h"
#include <memory>
#include <iostream>
class Subproblem; // forward declaration
class Label : public std::enable_shared_from_this<Label> {
// private members
public:
Label();
std::vector<std::shared_ptr<Node> > const PossibleMoves(Subproblem* const sp, int startLB, int startUB, int endLB, int endUB);
std::shared_ptr<Label> ExtendLabel(std::shared_ptr<Node> destinationNode, Subproblem* const sp, Duals duals);
};
bool CheckDominance(std::shared_ptr<Label> l1, std::shared_ptr<Label> l2);
std::ostream& operator<<(std::ostream& os, const std::shared_ptr<Label> l);
bool operator< (const std::shared_ptr<Label>& lhs, const std::shared_ptr<Label>& rhs);
Does anyone have any idea of what might be the problem and how I can resolve it? I'm using c 17 and g . I'm new to this forum so sorry if something is unclear or missing from my description.
g -std=c 17 -c -o Subproblem.o Subproblem.cpp
g -o program.exe -I/share/apps/gurobi/9.5.1/include/ main.o BBnode.o BBtree.o Heuristic.o Label.o MasterProblem.o Nodes.o Pattern.o Solution.o Subproblem.o TestInstance.o Utilities.o -lm -L/share/apps/gurobi/9.5.1/lib -lgurobi_g 5.2 -lgurobi_c -lgurobi95
/usr/bin/ld.gold: error: Label.o:1:1: invalid character
Subproblem.o:Subproblem.cpp:function Subproblem::FindPaths(Duals, int, int, int, int): error: undefined reference to 'Label::PossibleMoves(Subproblem*, int, int, int, int)'
Subproblem.o:Subproblem.cpp:function Subproblem::FindPaths(Duals, int, int, int, int): error: undefined reference to 'operator<<(std::ostream&, std::shared_ptr<Label>)'
Subproblem.o:Subproblem.cpp:function Subproblem::FindPaths(Duals, int, int, int, int): error: undefined reference to 'Label::ExtendLabel(std::shared_ptr<Node>, Subproblem*, Duals)'
Subproblem.o:Subproblem.cpp:function Subproblem::FindPaths(Duals, int, int, int, int): error: undefined reference to 'operator<<(std::ostream&, std::shared_ptr<Label>)'
Subproblem.o:Subproblem.cpp:function Subproblem::FindPaths(Duals, int, int, int, int): error: undefined reference to 'CheckDominance(std::shared_ptr<Label>, std::shared_ptr<Label>)'
Subproblem.o:Subproblem.cpp:function Subproblem::FindPaths(Duals, int, int, int, int): error: undefined reference to 'operator<<(std::ostream&, std::shared_ptr<Label>)'
Subproblem.o:Subproblem.cpp:function Subproblem::FindPaths(Duals, int, int, int, int): error: undefined reference to 'CheckDominance(std::shared_ptr<Label>, std::shared_ptr<Label>)'
Subproblem.o:Subproblem.cpp:function Subproblem::FindPaths(Duals, int, int, int, int): error: undefined reference to 'operator<<(std::ostream&, std::shared_ptr<Label>)'
Subproblem.o:Subproblem.cpp:function Subproblem::FindPaths(Duals, int, int, int, int): error: undefined reference to 'CheckDominance(std::shared_ptr<Label>, std::shared_ptr<Label>)'
Subproblem.o:Subproblem.cpp:function Subproblem::FindPaths(Duals, int, int, int, int): error: undefined reference to 'CheckDominance(std::shared_ptr<Label>, std::shared_ptr<Label>)'
Subproblem.o:Subproblem.cpp:function bool __gnu_cxx::__ops::_Iter_less_iter::operator()<__gnu_cxx::__normal_iterator<std::shared_ptr<Label>*, std::vector<std::shared_ptr<Label>, std::allocator<std::shared_ptr<Label> > > >, __gnu_cxx::__normal_iterator<std::shared_ptr<Label>*, std::vector<std::shared_ptr<Label>, std::allocator<std::shared_ptr<Label> > > > >(__gnu_cxx::__normal_iterator<std::shared_ptr<Label>*, std::vector<std::shared_ptr<Label>, std::allocator<std::shared_ptr<Label> > > >, __gnu_cxx::__normal_iterator<std::shared_ptr<Label>*, std::vector<std::shared_ptr<Label>, std::allocator<std::shared_ptr<Label> > > >) const: error: undefined reference to 'operator<(std::shared_ptr<Label> const&, std::shared_ptr<Label> const&)'
Subproblem.o:Subproblem.cpp:function bool __gnu_cxx::__ops::_Val_less_iter::operator()<std::shared_ptr<Label>, __gnu_cxx::__normal_iterator<std::shared_ptr<Label>*, std::vector<std::shared_ptr<Label>, std::allocator<std::shared_ptr<Label> > > > >(std::shared_ptr<Label>&, __gnu_cxx::__normal_iterator<std::shared_ptr<Label>*, std::vector<std::shared_ptr<Label>, std::allocator<std::shared_ptr<Label> > > >) const: error: undefined reference to 'operator<(std::shared_ptr<Label> const&, std::shared_ptr<Label> const&)'
Subproblem.o:Subproblem.cpp:function bool __gnu_cxx::__ops::_Iter_less_val::operator()<__gnu_cxx::__normal_iterator<std::shared_ptr<Label>*, std::vector<std::shared_ptr<Label>, std::allocator<std::shared_ptr<Label> > > >, std::shared_ptr<Label> >(__gnu_cxx::__normal_iterator<std::shared_ptr<Label>*, std::vector<std::shared_ptr<Label>, std::allocator<std::shared_ptr<Label> > > >, std::shared_ptr<Label>&) const: error: undefined reference to 'operator<(std::shared_ptr<Label> const&, std::shared_ptr<Label> const&)'
collect2: error: ld returned 1 exit status
make: *** [program.exe] Error 1
This is my Makefile:
CXX=g
CXXFLAGS= -std=c 17
src = $(wildcard *.cpp)
obj = $(src:.cpp=.o)
dep = $(obj:.o=.d)
LDFLAGS = -lm -L$(GUROBI_HOME)/lib -lgurobi_g 5.2 -lgurobi_c -lgurobi95
CPLUS_INCLUDE_PATH = -I$(GUROBI_HOME)/include/
all: program.exe
program.exe : main.o BBnode.o BBtree.o Heuristic.o Label.o MasterProblem.o Nodes.o Pattern.o Solution.o Subproblem.o TestInstance.o Utilities.o
$(CXX) -o program.exe $(CPLUS_INCLUDE_PATH) main.o BBnode.o BBtree.o Heuristic.o Label.o MasterProblem.o Nodes.o Pattern.o Solution.o Subproblem.o TestInstance.o Utilities.o $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) main.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) BBnode.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) BBtree.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) Heuristic.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) Label.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) MasterProblem.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) Nodes.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) Pattern.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) Solution.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) Subproblem.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) TestInstance.cpp $(LDFLAGS)
#$(CXX) -c $(CPLUS_INCLUDE_PATH) Utilities.cpp $(LDFLAGS)
-include $(dep)
.PHONY: clean
clean:
rm -f VRPTW.exe $(obj)
.PHONY: cleandep
cleandep:
rm -f $(dep)
Content of Label.cpp:
#include #include "Label.h"
#include "Subproblem.h"
#include <iostream>
#include <cstdlib>
#include <iterator>
#include <vector>
std::vector<std::shared_ptr<Node> > const
Label::PossibleMoves(Subproblem* const sp, int startLB, int startUB, int endLB, int endUB) { /* implementation */ }
std::shared_ptr<Label> Label::ExtendLabel(std::shared_ptr<Node> destinationNode, Subproblem* const sp, Duals duals){ /* implementation */ }
bool CheckDominance(std::shared_ptr<Label> l1, std::shared_ptr<Label> l2){ /* implementation */}
std::ostream& operator<<(std::ostream& os, const std::shared_ptr<Label> l){ /* implementation */}
bool operator< (const std::shared_ptr<Label>& lhs, const std::shared_ptr<Label>& rhs){ /* implementation*/ }
CodePudding user response:
If you look carefully at the error messages, you will see that there is a difference in arguments. For example, the error that complains about Label::PossibleMoves(Subproblem*, int, int, int, int)
takes a Subproblem*
, not a Subproblem *const
as written in your header and implementation file.
This makes me think that you're linking with an older version of Subproblem.o
, which hasn't been recompiled after you made some changes to Label.cpp
and Label.h
.
This makes sense, because the Makefile
relies on an implicit rule about how to make a .o
from a .cpp
, and the implicit rule assumes that the .o
only depends on the .cpp
. It does not scan the included headers to see if anything changed there; that task is normally done by some makefile generator like autotools or CMake, or manually written into the Makefile
itself.
In the old version of the Makefile
rule for program.exe
(commented out), there were a bunch of $(CXX)
invocations that would recompile every .cpp
every time something changed. A simple but crude solution.
If you just need to compile this once and get on with your life, try removing all .o
files and building from scratch. I suspect you'll get rid of these errors (and maybe get exciting new ones in return).
If you need a proper solution, look into CMake or some other makefile generator or build tool that does detect dependencies between source files.
CodePudding user response:
It's not the answer yet but try to use this Makefile:
CXX=g
CXXFLAGS= -std=c 17 -O2 -g
INCLUDES = -I$(GUROBI_HOME)/include
srcs = $(wildcard *.cpp)
objs = $(srcs:.cpp=.o)
deps = $(objs:.o=.d)
.cpp.o:
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
GUROBI_HOME=gurobi52
LIBS = -lm -L$(GUROBI_HOME)/lib -lgurobi_g 5.2 -lgurobi_c -lgurobi95
LDFLAGS =
all: program
program : $(objs)
$(CXX) $(LDFLAGS) -o $@ $^ $(LIBS)
-include $(dep)
.PHONY: clean
clean:
rm -f $(objs)
.PHONY: cleandep
cleandep:
rm -f $(deps)
Hopefully it's more legible and start from that.
Automatic variables in link $(CXX) $(LDFLAGS) -o $@ $^ $(LIBS)
is equivalent to $(CXX) $(LDFLAGS) -o program $(objs) $(LIBS)
.
Reading the answer from @Thomas, you need to clean it with $ make clean
.