Макет проекта
├── CMakeLists.txt
├── README.md
├── cppml.pc.in
├── examples
│ ├── AccuracyScoreEx.cpp
│ └── CMakeLists.txt
├── include
│ └── cppml
│ ├── Prerequisites.h
│ └── metrics
│ └── AccuracyScore.h
└── src
├── CMakeLists.txt
└── metrics
└── AccuracyScore.cpp
Содержимое корня CMakeLists.txt
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
project(cppml VERSION 1.0.1 LANGUAGES CXX)
include(GNUInstallDirs)
find_package(Armadillo REQUIRED)
configure_file(cppml.pc.in cppml.pc @ONLY)
add_subdirectory(src)
add_subdirectory(examples)
#add_subdirectory(tests)
Содержимое src/CMakeLists.txt
# set source files
set (sources
metrics/AccuracyScore.cpp
)
# define library targets
add_library(cppml SHARED
${sources}
)
# target properties
set_target_properties(cppml PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1
CXX_VISIBILITY_PRESET hidden
)
# define headers for this lib. PUBLIC headers are used for compiling
# the library, and will be added to user's build path.
target_include_directories(cppml PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE ${PROJECT_SOURCE_DIR}/src
)
# Link with externel libs
target_link_libraries(cppml ${ARMADILLO_LIBRARIES})
# target_compile_features(cppml
# PUBLIC
# cxx_std_11 #XXX: PROBLEM HERE!
# )
# Install
install(TARGETS cppml
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(FILES ${CMAKE_BINARY_DIR}/cppml.pc
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
)
Проблема в том, что когда я собираю проект с вышеуказанной настройкой, то это дает правильный результат:
g++ -o AccuracyScoreEx AccuracyScoreEx.cpp -lcppml
, но не это:
g++ -std=c++11 -o AccuracyScoreEx AccuracyScoreEx.cpp -lcppml
./AccuracyScoreEx
Segmentation fault: 11
Вот исходные коды:
Prerequisites.h
:
#ifndef INCLUDE_CPPML_PREREQUISITES_H_
#define INCLUDE_CPPML_PREREQUISITES_H_
// armadillo
#include <armadillo>
#endif // INCLUDE_CPPML_PREREQUISITES_H_
AccuracyScore.h
:
#ifndef INCLUDE_CPPML_METRICS_ACCURACYSCORE_H_
#define INCLUDE_CPPML_METRICS_ACCURACYSCORE_H_
#include "cppml/Prerequisites.h"
namespace cppml {
namespace metrics {
extern "C" double accuracy_score(const arma::ivec &y_true,
const arma::ivec &y_pred,
const bool normalize = true,
const arma::vec &sample_weight = arma::vec());
} // namespace metrics
} // namespace cppml
#endif // INCLUDE_CPPML_METRICS_ACCURACYSCORE_H_
AccuracyScore.cpp
:
#include "cppml/metrics/AccuracyScore.h"
#define EXPORT __attribute__((visibility("default")))
namespace cppml {
namespace metrics {
EXPORT
double accuracy_score(const arma::ivec &y_true,
const arma::ivec &y_pred,
const bool normalize,
const arma::vec &sample_weight) {
arma::uvec score = (y_true == y_pred);
arma::vec dscore = arma::conv_to<arma::vec>::from(score);
if (normalize) {
return (sample_weight.n_elem > 0) ?
arma::mean(dscore % sample_weight) :
arma::mean(dscore);
} else if (sample_weight.n_elem > 0) {
return arma::dot(dscore, sample_weight);
} else {
return arma::sum(dscore);
}
}
} // namespace metrics
} // namespace cppml
После небольшого взлома с gdb
оказывается, что этот парень y_true == y_pred
(поэлементное сравнение, выдает либо 0
, либо 1
) вызывает проблему segmentation fault
.Но почему это произошло только при включенном '-std = c ++ 11'?
Редактировать : Добавлен пример программы AccuracyScoreEx.cpp
:
#include <iostream>
#include <cppml/metrics/AccuracyScore.h>
int main(int argc, char **argv) {
arma::ivec y_true;
y_true << -1 << 1 << 1 << 1;
arma::ivec y_pred;
y_pred << 1 << 1 << -1 << 1;
std::cout << "Accuracy score: ";
std::out << cppml::metrics::accuracy_score(y_true, y_pred);
return 0;
}
Любая помощь будет принята с благодарностью!