将程序与未定义的符号链接时遇到问题

时间:2018-06-11 18:09:26

标签: c++ cmake clion accelerated-c++

我是c ++的新学习者,当我在推荐的书籍Accelerated C ++中重复代码示例时,我遇到了麻烦: 这是目录结构:

./Project
    |
    +--- main.cpp
    |
    +--- lib/
          |
          +--- grade.cpp
          |
          +--- grade.h
          +--- grade.cpp
          |
          +--- median.h
          +--- median.cpp
          |
          +--- Student_info.h
          +--- Student_info.cpp

的main.cpp

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <ios>
#include <stdexcept>
#include <string>
#include <vector>
#include "lib/median.h"
#include "lib/grade.h"
#include "lib/Student_info.h"
using namespace std;

int main(){
    vector<Student_info> students;
    Student_info record;
    string::size_type maxlen=0;
    while (read(cin,record)){
        maxlen=max(maxlen,record.name.size());
        students.push_back(record);

    }
    sort(students.begin(),students.end(),compare);
    for(vector<Student_info>::size_type i=0;i!=students.size();++i) {
        cout << students[i].name << string(maxlen + 1 - students[i].name.size(), ' ');
         try{
             double final_grade=grade(students[i]);
             streamsize prec=cout.precision();
             cout<<setprecision(3)<<final_grade<<setprecision(prec);


        }catch(domain_error e){
             cout<<e.what();
         }

        cout<<endl;
    }


    return  0;
}

grade.cpp

//
// Created by steafan on 2018/6/10.
//
#include "Student_info.h"
#include "median.h"
#include "grade.h"
#include <stdexcept>
#include <vector>




using std::domain_error;
using std::vector;
double grade(double midterm,double final,double homework){
    return 0.2*midterm+0.4*final+0.4*homework;
}

/*
 const means no change,& means a reference,not a copy of value
 */
double grade(double midterm,double final,const vector<double>& hw){
    if(hw.size()==0){
        throw domain_error("student has done no homework");
    }
    return grade(midterm,final,median(hw));
}
double grade(const Student_info& s){
    return grade(s.midterm,s.final,s.homework);
}

grade.h

#ifndef UNTITLED_GRADE_H
#define UNTITLED_GRADE_H

#include <vector>
#include "Student_info.h"
double grade(double,double,double);
double grade(double,double,const std::vector<double>&);
double grade(const Student_info&);
#endif 

Student_info.h

#ifndef UNTITLED_STUDENT_INFO_H
#define UNTITLED_STUDENT_INFO_H

#include <istream>
#include <string>
#include <vector>
struct Student_info{
    std::string name;
    double midterm,final;
    std::vector<double> homework;

};
bool compare(const Student_info&,const Student_info&);
std::istream& read(std::istream&,Student_info&);
std::istream& read_hw(std::istream& , std::vector<double>&);
#endif //UNTITLED_STUDENT_INFO_H

Student_info.cpp

#include "Student_info.h"
#include <istream>
#include <string>
#include <vector>

using std::istream;
using std::vector;

bool compare(const Student_info& x,const Student_info& y){
    return x.name<y.name;
}
istream& read(istream& is,Student_info& s){
    is>>s.name>>s.midterm>>s.final;
    read_hw(is,s.homework);
    return is;
}
istream& read_hw(istream& in,vector<double>& hw){
    if(in){
        hw.clear();   //clear all the content in vector
        double x;
        while(in >> x){
            hw.push_back(x);
        }
        in.clear();  //reset cin state
    }
    return in;
}

median.cpp

#include "median.h"
#include <vector>
#include <algorithm>
#include <stdexcept>

using std::domain_error;
using std::sort;
using std::vector;

inline double median(vector<double> vec){
    typedef vector<double>::size_type  vec_sz;
    vec_sz size=vec.size();
    if(size==0)
        throw domain_error("meidan of an empty vector");
    sort(vec.begin(),vec.end());
    vec_sz mid=size/2;
    return size%2==0?(vec[mid]+vec[mid-1])/2:vec[mid];
}

median.h

#ifndef chap5_MEDIAN_H
#define chap5_MEDIAN_H

#include <vector>
#include <algorithm>
#include <stdexcept>
double median(std::vector<double>);
#endif //UNTITLED_MEDIAN_H

我收到链接器错误,我无法修复:

Scanning dependencies of target STUDENT
[ 16%] Building CXX object grade-refactor/lib/CMakeFiles/STUDENT.dir/Student_info.cpp.o
[ 33%] Linking CXX static library libSTUDENT.a
/Library/Developer/CommandLineTools/usr/bin/ranlib: file: libSTUDENT.a(median.cpp.o) has no symbols
/Library/Developer/CommandLineTools/usr/bin/ranlib: file: libSTUDENT.a(median.cpp.o) has no symbols
[ 66%] Built target STUDENT
Scanning dependencies of target grade-refactor
[ 83%] Building CXX object grade-refactor/CMakeFiles/grade-refactor.dir/main.cpp.o
[100%] Linking CXX executable grade-refactor
Undefined symbols for architecture x86_64:
  "median(std::__1::vector<double, std::__1::allocator<double> >)", referenced from:
      grade(double, double, std::__1::vector<double, std::__1::allocator<double> > const&) in libSTUDENT.a(grade.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [grade-refactor/grade-refactor] Error 1
make[2]: *** [grade-refactor/CMakeFiles/grade-refactor.dir/all] Error 2
make[1]: *** [grade-refactor/CMakeFiles/grade-refactor.dir/rule] Error 2
make: *** [grade-refactor] Error 2

主文件夹的CMakeList.txt:

set(CMAKE_CXX_STANDARD 11)
include_directories(${PROJECT_SOURCE_DIR}/grade-refactor/lib)
add_subdirectory(lib)


ADD_EXECUTABLE(grade-refactor main.cpp )
target_link_libraries(grade-refactor STUDENT)

对于lib文件夹:

 add_library(STUDENT  grade.cpp  median.cpp grade.h median.h Student_info.cpp Student_info.h)

我正在使用macos / Clion / Gcc组合,我做错了什么?我是C ++的新手,我们将不胜感激。

0 个答案:

没有答案