Project layout
├── 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
Content of root 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)
Content of 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
)
The problem is, when I build the project with the above setup, then this produces the correct result:
g++ -o AccuracyScoreEx AccuracyScoreEx.cpp -lcppml
but not this:
g++ -std=c++11 -o AccuracyScoreEx AccuracyScoreEx.cpp -lcppml
./AccuracyScoreEx
Segmentation fault: 11
Here is the source codes:
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
After hacking around a bit with gdb
, it turns out that this guy y_true == y_pred
(element-wise comparison, produces either 0
or 1
) causes the segmentation fault
problem. But why it only happened when '-std=c++11' turned on?
Any help would be greatly appreciated!
Aucun commentaire:
Enregistrer un commentaire