I have a relatively simple question about building a C++ project with cmake
. I'm unable properly import functions from a source file into another. I have a minimum working example in a project folder structured as follows.
.
├── CMakeLists.txt
├── README.md
├── include
│ └── print.hpp
└── src
├── main.cpp
└── print.cpp
I have two files in src/
: main.cpp
and print.cpp
. The latter contains functions to print the contents of a vector, and main.cpp
tries to use these functions to print out the elements of some example vector. My CMakeLists.txt
is specified as follows.
cmake_minimum_required(VERSION 3.0.0)
set(CMAKE_CXX_COMPILER "g++-11")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
project(tests VERSION 1.0)
set(SOURCE_FILES
src/print.cpp
)
add_executable(tests
src/main.cpp
${SOURCE_FILES}
)
target_link_libraries (tests Eigen3::Eigen)
target_include_directories(tests PUBLIC include)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
The main.cpp
file contains:
#include <vector>
#include <numeric>
#include <algorithm>
#include <iostream>
#include "print.hpp"
using namespace std;
int main() {
cout << "Testing C++ functions." << endl;
vector<vector<double>> weights(3);
weights[0] = {0.1, 0.9};
weights[1] = {0.3, 0.4, 0.3};
weights[2] = {0.2, 0.1, 0.5, 0.2};
vector<int> sizes(weights.size());
int i;
for (i = 0; i < weights.size(); i ++)
sizes[i] = weights[i].size();
print_vector2D<vector<vector<double>>>(weights, "Weights");
print_vector1D<vector<int>>(sizes, "Sizes");
return 0;
}
and print.cpp
contains:
#include <string>
#include <iostream>
using namespace std;
template <class generic_type>
void print_vector2D(generic_type vect, string name){
// Print the contents of a Vector.
cout << name << endl;
int i, j;
for (i = 0; i < vect.size(); i ++){
cout << vect[i][0];
for (j = 1; j < vect[i].size(); j ++)
cout << " " << vect[i][j];
cout << endl;
}
}
template <class generic_type>
void print_vector1D(generic_type vect, string name){
// Print the contents of a Vector.
cout << name << endl;
int i;
cout << vect[0];
for (i = 1; i < vect.size(); i ++)
cout << " " << vect[i];
cout << endl;
}
Finally, print.hpp
has the function headers.
#ifndef PRINT_HPP
#define PRINT_HPP PRINT_HPP
#include <string>
using namespace std;
// Print the contents of a Vector.
template <class generic_type>
void print_vector2D(generic_type vect, string name);
// Print the contents of a Vector.
template <class generic_type>
void print_vector1D(generic_type vect, string name);
#endif
When I build the project using cmake
following the four steps below:
mkdir -p build/
cmake .
cd build
cmake --build ../
I get an error that reflects missing links to the print functions called from main.
(base) pavithran@MBA-FVFGJ3FGQ6LR build % cmake --build ../
Consolidate compiler generated dependencies of target tests
[ 33%] Building CXX object CMakeFiles/tests.dir/src/main.cpp.o
[ 66%] Linking CXX executable tests
Undefined symbols for architecture arm64:
"__Z14print_vector1DISt6vectorIiSaIiEEEvT_NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
_main in main.cpp.o
"__Z14print_vector2DISt6vectorIS0_IdSaIdEESaIS2_EEEvT_NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture arm64
collect2: error: ld returned 1 exit status
make[2]: *** [tests] Error 1
make[1]: *** [CMakeFiles/tests.dir/all] Error 2
make: *** [all] Error 2
I believe this is due to an incorrect way of including the header files in the project. Could someone give me a hint as to what is the right way?
Aucun commentaire:
Enregistrer un commentaire