FALCONN-LIB / FALCONN

FAst Lookups of Cosine and Other Nearest Neighbors (based on fast locality-sensitive hashing)
http://falconn-lib.org/
MIT License
1.14k stars 194 forks source link

The header-only library seems broken #115

Open 1flei opened 5 years ago

1flei commented 5 years ago

When I try to include "falconn/lsh_nn_table.h" from multiple cpp files, it will cause "multiple definition of ***" linking error for a lot of fht functions, whereas "normal" header-only library should not have this problem (e.g. Eigen).

A minimum example that triggers this problem may be like: a.cpp

include "falconn/lsh_nn_table.h"

b.cpp

include "falconn/lsh_nn_table.h"

main.cpp

include

int main() { std::cout << "hello world" << std::endl; return 0; }

CMakeLists.txt PROJECT(TEST_FALCONN)

set (CMAKE_CXX_STANDARD 17)

include_directories("FALCONN/src/include") include_directories("FALCONN/external/simple-serializer") include_directories("FALCONN/external/eigen")

ADD_EXECUTABLE(test ${DIR_SRCS} "a.cpp" "b.cpp" "main.cpp" )

and when linking a.o and b.o together, it will report multiple definition of ** (e.g. helperfloat/helperdouble*/...).

I tried cmake 3.12.0 and gcc/g++6.5/8.0 although I do not think it is the problem of the version of compiler/toolchain.

OancaAndrei commented 3 years ago

I was facing the same issue. After some digging, I've patched it by moving the last include line from lsh_nn_table.h:

#include "wrapper/cpp_wrapper_impl.h"

to a new file lsh_nn_table_impl.h:

#ifndef __WRAPPER_IMPL_H__
#define __WRAPPER_IMPL_H__

#include "lsh_nn_table.h"
#include "wrapper/cpp_wrapper_impl.h"

#endif

The trick is to include only once per "project" the lsh_nn_table_impl.h file, ideally in one of your cpp files (so the definitions lay in only one object file of your project) and then use lsh_nn_table.h where needed across your project.