CMake 链接器无法识别头文件
CMake linker does not recognized the header file
我是Linux编程的初学者,这是我的问题。我的项目是由C++在Linux环境中编写的OpenCV项目。为了编译,我使用 CMake 构建一个 Makefile 并运行。为了说清楚,我也是玩CMake的新手。
首先,我有一个主要.cpp一切开始的地方:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cstdio>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#include <vector>
#include <cmath>
#include <dirent.h>
#include <algorithm>
#include <string.h>
using namespace std;
#include "constants.h"
#include "readData.cpp"
#include "features.cpp"
#include "featuresRGBD.cpp"
bool USE_HOG = true;
// print error message
void errorMsg(string message) {
cout << "ERROR! " << message << endl;
exit(1);
}
正如我们所看到的,我包含了一些预定义的文件:constants.h,readData.cpp,features.cpp和featuresRGBD.cpp
在 constaints.cpp 中,我设置了一些常量变量:
const int SLEEP_TIME = 0;
const int JOINT_NUM = 11;
const int JOINT_DATA_ORI_NUM = 9;
const int JOINT_DATA_POS_NUM = 3;
const int JOINT_DATA_NUM = (JOINT_DATA_ORI_NUM+JOINT_DATA_POS_NUM);
const int JOINT_DATA_TYPE_NUM = 2; // two types : orientation and xyz position
const int TORSO_JOINT_NUM = 2;
const int HEAD_JOINT_NUM = 0;
const int POS_JOINT_NUM = 4;
const int POS_JOINT_DATA_NUM = 3;
const int POS_LEFT_HAND_NUM = 0;
const int POS_RIGHT_HAND_NUM = 1;
const int POS_LEFT_FOOT_NUM = 2;
const int POS_RIGHT_FOOT_NUM = 3;
const int X_RES = 320;
const int Y_RES = 240;
const int RGBD_data = 4;
// 30 fps
const int frameStoreNum = 66;
const int compareFrame[] = {0, -5, -9, -14, -20, -27, -35, -44, -54, -65};
const int compareFrameNum = sizeof(compareFrame)/sizeof(compareFrame[0]);
在 readData.cpp 中,我使用常量中的一些常量实现了我的方法.cpp
bool READ_FROM_PNG = true;
class readData {
private:
int currentFrameNum;
int currentFrameNum_RGBD;
int lastFrame;
string dataLocation;
string dataLocation_mirrored;
string fileName;
string fileName_skeleton;
string fileName_RGBD;
string curActivity;
map<string, string> data_act_map;
ifstream* file;
ifstream* file_RGBD;
bool mirrored;
// print error message
void errorMsg(string message, bool exitProgram) {
cout << "ERROR! " << message << endl;
printf("tcurrentFrameNum = %dn", currentFrameNum);
printf("tcurrentFrameNum_RGBD = %dn", currentFrameNum_RGBD);
if (exitProgram) {
exit(1);
}
}
void errorMsg(string message) {
errorMsg(message, true);
}
bool parseChk(bool chk, bool skeleton) {
if (!chk) {
if (skeleton) {
errorMsg("parsing error. (skeleton)", true);
} else {
errorMsg("parsing error. (RGBD) - IGNORE THIS ERROR!! (all random dataset will hit this error)", false);
}
return false;
}
return true;
}
// read skeleton data file
void prepareSkeletonData() {
curActivity = data_act_map[fileName];
if (!mirrored) {
fileName_skeleton = dataLocation + fileName + ".txt";
} else {
fileName_skeleton = dataLocation_mirrored + fileName + ".txt";
}
printf("tOpening "%s" (%s)n", (char*)fileName_skeleton.c_str(), (char*)curActivity.c_str());
file = new ifstream((char*)fileName_skeleton.c_str(), ifstream::in);
currentFrameNum = -99;
}
void closeSkeletonData() {
file->close();
printf("tskeleton file closedn");
}
// return true if data retrieving was successful
bool readNextLine_skeleton(double **data, double **pos_data, int **data_CONF, int *data_pos_CONF) {
string line;
bool file_ended = true;
if (getline(*file,line)) {
file_ended=false;
stringstream lineStream(line);
string element;
int jointCount=0;
int joint_dataCount = 0;
int pos_jointCount = 0;
int pos_joint_dataCount = 0;
parseChk(getline(lineStream, element, ','), true);
currentFrameNum = atoi((char*)element.c_str());
if (element.compare("END") == 0) {
file_ended = true;
return false;
}
while (getline(lineStream, element, ',')) {
double e = strtod((char*)element.c_str(), NULL);
if (jointCount < JOINT_NUM) {
data[jointCount][joint_dataCount] = e;
joint_dataCount++;
if (joint_dataCount == JOINT_DATA_ORI_NUM) {
parseChk(getline(lineStream, element, ','), true); // ori conf value
data_CONF[jointCount][0] = atoi((char*)element.c_str());
} else if (joint_dataCount >= JOINT_DATA_NUM) {
parseChk(getline(lineStream, element, ','), true); // pos conf value
data_CONF[jointCount][1] = atoi((char*)element.c_str());
jointCount++;
joint_dataCount = 0;
}
} else {
// pos only joints
if (pos_jointCount >= POS_JOINT_NUM) {
errorMsg("PARSING ERROR!!!!!");
}
pos_data[pos_jointCount][pos_joint_dataCount] = e;
pos_joint_dataCount++;
if (pos_joint_dataCount >= POS_JOINT_DATA_NUM) {
parseChk(getline(lineStream, element, ','), true); // pos conf value
data_pos_CONF[pos_jointCount] = atoi((char*)element.c_str());
pos_jointCount++;
pos_joint_dataCount = 0;
}
}
}
// check if there is more data in current frame..
if (getline(lineStream, element,',')) {
errorMsg("more data exist in skeleton data ..n");
}
}
if (currentFrameNum == -99) {
errorMsg("file does not exist or empty!!");
}
return !file_ended;
}
// read RGBD data file
void prepareRGBDData() {
fileName_RGBD = dataLocation + fileName + "_rgbd.txt";
printf("tOpening "%s" (%s)n", (char*)fileName_RGBD.c_str(), (char*)curActivity.c_str());
file_RGBD = new ifstream((char*)fileName_RGBD.c_str(), ifstream::in);
currentFrameNum = -99;
}
void closeRGBDData() {
file_RGBD->close();
printf("tRGBD file closedn");
}
// return true if data retrieving was successful
bool readNextPNG(int ***data) {
stringstream ss;
ss << currentFrameNum;
fileName_RGBD = dataLocation + fileName + "/RGB_" + ss.str() +".png";
string fileName_Depth = dataLocation + fileName + "/Depth_" + ss.str() +".png";
if (currentFrameNum == 1) {
printf("tOpening "%s" and so forth..n",
(char*)fileName_RGBD.c_str());
printf("tOpening "%s" and so forth..n",
(char*)fileName_Depth.c_str());
}
// Load an image from file
cv::Mat rgbImage = cv::imread((char*)fileName_RGBD.c_str(),1);
cv::Mat colorArr[3];
cv::split(rgbImage, colorArr);
cv::Mat depthImage = cv::imread((char*)fileName_Depth.c_str(),-1);
if (rgbImage.data == NULL) {
printf("ERROR! Unable to open file %s.n", (char*)fileName_RGBD.c_str());
exit(1);
}
if (depthImage.data == NULL) {
printf("ERROR! Unable to open file %s.n", (char*)fileName_Depth.c_str());
exit(1);
}
for (int y=0; y<Y_RES; y++){
// opencv uses BGR order
uchar* Bptr = colorArr[0].ptr<uchar>(y);
uchar* Gptr = colorArr[1].ptr<uchar>(y);
uchar* Rptr = colorArr[2].ptr<uchar>(y);
ushort* IRptr = depthImage.ptr<ushort>(y);
for(int x=0;x<X_RES; x++){
// our data is stored in RGB order
data[x][y][0] = Rptr[x];
data[x][y][1] = Gptr[x];
data[x][y][2] = Bptr[x];
data[x][y][3] = IRptr[x];
}
}
return true;
}
// return true if data retrieving was successful
bool readNextLine_RGBD(int ***IMAGE) {
string line;
char* line_c;
bool file_ended = true;
if (getline(*file_RGBD,line)) {
file_ended = false;
line_c = (char*)line.c_str();
char* element = strtok(line_c, ",");
if (element == NULL || strcmp(element,"END") == 0) {
file_ended = true;
return false;
}
currentFrameNum_RGBD = atoi(element);
if (currentFrameNum != currentFrameNum_RGBD) {
printf("skeleton: %d rgbd: %dn", currentFrameNum, currentFrameNum_RGBD);
errorMsg("FRAME NUMBER BETWEEN SKELETON AND RGBD DOES NOT MATCH!!!!!!!!! (READING RGBD)");
}
for (int y=0;y<Y_RES;y++) {
for (int x=0;x<X_RES;x++) {
for (int d = 0; d<RGBD_data; d++) {
element = strtok(NULL, ","); // passing NULL keeps tokenizing previous call
if (element == NULL) {
file_ended = true;
return false;
}
int e = atoi(element);
if (!mirrored) {
IMAGE[x][y][d] = e;
} else {
IMAGE[x][(Y_RES-1)-y][d] = e;
}
}
}
}
// check if there is more data in current frame..
element = strtok(NULL, ",");
if (element != NULL) {
printf("line_c = %sn", line_c);
errorMsg("more data exist in RGBD data ..n");
}
}
return !file_ended;
}
public:
// return true if data retrieving was successful
bool readNextFrame(double **data, double **pos_data, int **data_CONF, int *data_pos_CONF, int ***IMAGE) {
if (currentFrameNum % 100 == 0) {
printf("tt(progress..) frame num = %dn", currentFrameNum);
}
bool status = readNextLine_skeleton(data,pos_data, data_CONF, data_pos_CONF);
if (!status) {
printf("tttotal number of frames = %dn", lastFrame);
return false;
}
bool status_RGBD;
if (!READ_FROM_PNG) {
status_RGBD = readNextLine_RGBD(IMAGE);
} else {
status_RGBD = readNextPNG(IMAGE);
}
if (status_RGBD) {
lastFrame = currentFrameNum;
} else {
printf("tttotal number of frames = %dn", lastFrame);
}
return status_RGBD;
}
readData(string dataLoc, string fileN, map<string, string> d_a_map, int i, bool mirrored, string dataLoc_mirrored) {
if (!mirrored) {
printf("%d. ", i);
} else {
printf("%d(M). ", i);
}
dataLocation = dataLoc;
dataLocation_mirrored = dataLoc_mirrored;
fileName = fileN;
data_act_map = d_a_map;
this->mirrored = mirrored;
prepareSkeletonData();
if (!READ_FROM_PNG) {
prepareRGBDData();
}
}
readData() {
}
~readData(){
closeSkeletonData();
if (!READ_FROM_PNG) {
closeRGBDData();
}
printf("n");
}
};
并继续到其他文件,我也使用了一些预定义的常量。然后,我编写CMakeLists.txt以便构建MakeFiles,如下所示:
cmake_minimum_required(VERSION 2.8)
project( FeatureExtractor )
find_package( OpenCV REQUIRED )
add_executable( FeatureExtractor main.cpp readData.cpp features.cpp featuresRGBD.cpp HOG.cpp HOGFeaturesOfBlock.cpp)
target_link_libraries( FeatureExtractor ${OpenCV_LIBS} )
由于我在某处读到,他们说"CMake 自动处理依赖项,因此不需要列出标头",所以我没有在配置 CMakeLists.txt 中提及头文件 (constaint.h)。
然后,当我运行命令以组合和构建 Makefile 时,我遇到了此错误
make
Scanning dependencies of target FeatureExtractor
[ 16%] Building CXX object CMakeFiles/FeatureExtractor.dir/main.cpp.o
[ 33%] Building CXX object CMakeFiles/FeatureExtractor.dir/readData.cpp.o
/home/minhthanh/Downloads/Test/readData.cpp:11:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:12:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:13:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:14:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:15:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:16:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:17:5: error: ‘map’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:18:5: error: ‘ifstream’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:19:5: error: ‘ifstream’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:24:19: error: ‘string’ has not been declared
/home/minhthanh/Downloads/Test/readData.cpp:34:19: error: ‘string’ has not been declared
/home/minhthanh/Downloads/Test/readData.cpp:287:21: error: expected ‘)’ before ‘dataLoc’
/home/minhthanh/Downloads/Test/readData.cpp:317:2: error: expected ‘}’ at end of input
/home/minhthanh/Downloads/Test/readData.cpp: In member function ‘void readData::errorMsg(int, bool)’:
/home/minhthanh/Downloads/Test/readData.cpp:25:9: error: ‘cout’ was not declared in this scope
/home/minhthanh/Downloads/Test/readData.cpp:25:41: error: ‘endl’ was not declared in this scope
/home/minhthanh/Downloads/Test/readData.cpp:26:59: error: ‘printf’ was not declared in this scope
/home/minhthanh/Downloads/Test/readData.cpp:30:19: error: ‘exit’ was not declared in this scope
/home/minhthanh/Downloads/Test/readData.cpp: In member function ‘bool readData::parseChk(bool, bool)’:
/home/minhthanh/Downloads/Test/readData.cpp:43:59: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]
/home/minhthanh/Downloads/Test/readData.cpp:24:10: error: initializing argument 1 of ‘void readData::errorMsg(int, bool)’ [-fpermissive]
/home/minhthanh/Downloads/Test/readData.cpp:45:119: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]
/home/minhthanh/Downloads/Test/readData.cpp:24:10: error: initializing argument 1 of ‘void readData::errorMsg(int, bool)’ [-fpermissive]
/home/minhthanh/Downloads/Test/readData.cpp: In member function ‘void readData::prepareSkeletonData()’:
/home/minhthanh/Downloads/Test/readData.cpp:54:9: error: ‘curActivity’ was not declared in this scope
/home/minhthanh/Downloads/Test/readData.cpp:54:23: error: ‘data_act_map’ was not declared in this scope
虽然这是一个很长的列表,但我想问题是我在main中包含的一些库和文件.cpp在下面的文件(readData.cpp,功能.cpp,...)中无法识别。
如何配置或修改以便我在下面包含的那些文件可以识别那些预定义的文件和库?
问题是 CMake 单独编译 readData.cpp并且其中没有包含 <string>
和 using namespace std;
,因此它不会编译。
当您在main中包含readData.cpp,features.cpp,featuresRGBD等.cpp.cpp(如您所见)时,您无需在CMake中设置它们以进行单独编译,即将它们从CMake add_executable(...
行中删除。
但一般来说,通常以另一种方式进行,即分别编译每个 *.cpp,不将其包含在 main.cpp 中,并且#include ...
每个中只需要它们需要的东西。
- 我有两个类需要在同一 cpp 文件中相互引用,但第一个类无法识别第二个类类型的对象
- 如何识别项目是 QT 中的文件还是文件夹
- 无法识别 Mac c++ 文件系统库
- 我的头文件 DNode 中的我的数据类型未被识别为数据类型
- G++ 编译器无法识别 SQLAPI.h 头文件
- 生成库失败:无法识别文件格式;作为链接器脚本处理
- 从文件读取时"n"无法识别
- 如何让 + 重载在另一个文件C++中被识别?
- /usr/bin/ld: build-debug/obj/gpsitem.o: 文件无法识别: 文件被截断
- Visual Studio 停止识别任何包含文件
- "生成"无法识别文件正在被修改
- ifstream识别文件的末端
- 尝试生成makefile时无法识别文件格式
- 识别 C 文件和包含的头文件之间依赖关系的工具/方法
- Arduino IDE不识别.c文件是.cpp
- 链接c++静态库与android ndk时出错(错误:无法识别文件格式)
- 无法识别文件格式;作为链接器脚本处理
- 无法识别.h文件中定义的typedef类型
- 识别文件中的音频样本
- 文件无法识别:文件被截断的GCC错误