CMake: как связать библиотеку A с библиотекой B, затем связать исполняемый файл с библиотекой A - PullRequest
0 голосов
/ 23 октября 2018
.
├── CMakeLists.txt
├── image.cpp
├── image.h
├── io_tools.h
├── libio_tools.so
└── main.cpp
  • image.h и image.cpp определяют класс Image.
  • image.cpp необходимо использовать функции из libio_tools.so, а io_tools.h - файл заголовка этой библиотеки.
  • main.cpp предназначен для тестирования класса Image.

Я хочу связать библиотеку A (image.cpp) с библиотекой B (libio_tools.so), а затем связать исполняемый файл (main.cpp) в библиотеку A.

Ниже мой CMakeLists.txt:

cmake_minimum_required( VERSION 2.8 )
set (CMAKE_CXX_STANDARD 11)
set( CMAKE_BUILD_TYPE "Debug" )
project(debug)

find_library(IO_TOOLS io_tools "${PROJECT_SOURCE_DIR}")
if(NOT IO_TOOLS)
  message(FATAL_ERROR "iotools library not found" )
endif()

add_library(image image.cpp)
target_link_libraries(image ${IO_TOOLS})
add_executable(bin_main main.cpp)
target_link_libraries(bin_main image)

После того, как я его собрал, я получил ошибку

[cmake] Configuring done
[cmake] Generating done
[build] Starting build
[proc] Executing command: /usr/local/bin/cmake --build /home/lm/debug/build --config Debug --target all -- -j 6
[build] [ 50%] Built target image
[build] [ 75%] Linking CXX executable bin_main
[build] CMakeFiles/bin_main.dir/main.cpp.o: In function `main':
[build] /home/lm/debug/main.cpp:4: undefined reference to `igg::Image::Image(int, int)'
[build] /home/lm/debug/main.cpp:6: undefined reference to `igg::Image::at(int, int)'
[build] /home/lm/debug/main.cpp:7: undefined reference to `igg::Image::WriteToPgm(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
[build] collect2: error: ld returned 1 exit status
[build] make[2]: *** [bin_main] Error 1
[build] make[1]: *** [CMakeFiles/bin_main.dir/all] Error 2
[build] CMakeFiles/bin_main.dir/build.make:85: recipe for target 'bin_main' failed
[build] CMakeFiles/Makefile2:72: recipe for target 'CMakeFiles/bin_main.dir/all' failed
[build] Makefile:83: recipe for target 'all' failed
[build] make: *** [all] Error 2
[build] Build finished with exit code 2

Я думаю, что тамчто-то не так с CMakeLists.txt.

Ниже приведены мои коды:

main.cpp:

#include "image.h"

int main(int argc, char const *argv[]) {
  igg::Image test(100, 100);
  for (int i = 0; i < 50; i++)
    for (int j = 0; j < 50; j++) test.at(i, j) = 255;
  test.WriteToPgm("test.pgm");
  return 0;
}

image.h:

#pragma once

#include <string>
#include <vector>

namespace igg {

class Image {
 public:
  ///////////////////// Create the public interface here ///////////////////////
  Image();
  Image(int rows, int cols);
  int rows() const;  // const function
  int cols() const;
  int& at(int rows, int cols);
  bool FillFromPgm(const std::string& file_name);
  void WriteToPgm(const std::string& file_name);

 private:
  int rows_ = 0;
  int cols_ = 0;
  int max_val_ = 255;
  std::vector<int> data_;
};

}  // namespace igg

image.cpp:

#include <iostream>
#include <string>
#include <vector>
#include "io_tools.h"
namespace igg {
class Image {
 public:
  ///////////////////// Create the public interface here ///////////////////////
  Image() : rows_(10), cols_(10), data_(std::vector<int>(100, 0)) {}
  Image(int rows, int cols)
      : rows_(rows), cols_(cols), data_(std::vector<int>(rows * cols, 0)) {}
  int rows() const { return rows_; }  // const function
  int cols() const { return cols_; }
  int& at(int rows, int cols) { return data_[rows * rows_ + cols]; }
  bool FillFromPgm(const std::string& file_name) {
    igg::io_tools::ImageData tmp = igg::io_tools::ReadFromPgm(file_name);
    if (tmp.cols == 0) return false;
    rows_ = tmp.rows;
    cols_ = tmp.cols;
    data_ = tmp.data;
    return true;
  }
  void WriteToPgm(const std::string& file_name) {
    igg::io_tools::ImageData image_data = {rows_, cols_, max_val_, data_};
    if (igg::io_tools::WriteToPgm(image_data, file_name))
      std::cout << "write " + file_name + " successfully!" << '\n';
    else
      std::cout << "write not successful!" << '\n';
  }

 private:
  int rows_ = 0;
  int cols_ = 0;
  int max_val_ = 255;
  std::vector<int> data_;
};
}  // namespace igg

io_tools.h:

#pragma once

#include <fstream>
#include <string>
#include <vector>

namespace igg {
namespace io_tools {

/// Dummy structure to store relevant image data.
struct ImageData {
  int rows;
  int cols;
  int max_val;
  std::vector<int> data;
};

/// Reads from a pgm image from ascii file. Returns empty ImageData if the path
/// is not found or any errors have occured while reading.
ImageData ReadFromPgm(const std::string& file_name);

/// Write image data into an ascii pgm file. Return true if successful.
bool WriteToPgm(const ImageData& image_data, const std::string& file_name);

}  // namespace io_tools
}  // namespace igg

1 Ответ

0 голосов
/ 23 октября 2018

Мои друзья помогли мне найти проблему.CMakeLists.txt является правильным.Проблема в image.cpp.

image.cpp должно быть:

#include "image.h"
#include <iostream>
#include <string>
#include <vector>
#include "io_tools.h"

namespace igg{
Image::Image() : rows_(10), cols_(10), data_(std::vector<int>(100, 0)) {}
Image::Image(int rows, int cols)
    : rows_(rows), cols_(cols), data_(std::vector<int>(rows * cols, 0)) {}
int Image::rows() const { return rows_; }  // const function
int Image::cols() const { return cols_; }
int& Image::at(int rows, int cols) { return data_[rows * rows_ + cols]; }
bool Image::FillFromPgm(const std::string& file_name) {
  igg::io_tools::ImageData tmp = igg::io_tools::ReadFromPgm(file_name);
  if (tmp.cols == 0) return false;
  rows_ = tmp.rows;
  cols_ = tmp.cols;
  data_ = tmp.data;
  return true;
}
void Image::WriteToPgm(const std::string& file_name) {
  igg::io_tools::ImageData image_data = {rows_, cols_, max_val_, data_};
  if (igg::io_tools::WriteToPgm(image_data, file_name))
    std::cout << "write " + file_name + " successfully!" << '\n';
  else
    std::cout << "write not successful!" << '\n';
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...