Click here to Skip to main content
15,891,905 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm porting something I implemented in Python to c++ for speed. I'm brand new to the cmake/clang build system but I've written up most of what I need. I'm stuck on an error that seems unsolvable; the exact code block from a library's example implementation (that runs fine in their testing suite) throws an error that persists through libc++ and libstdc++ and all available build systems. WTF??

Here's the error:

C++
1 warning generated.
Linking CXX executable BloomBloomier
Undefined symbols for architecture x86_64:
  "bloomier::BloomierFilter::BloomierFilter(int, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, int> > >*, int, int, int)", referenced from:
      bloomBloomier::instantiate(int, float) in main.cpp.o
  "bloomier::BloomierFilter::~BloomierFilter()", referenced from:
      bloomBloomier::instantiate(int, float) in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [BloomBloomier] Error 1
make[2]: *** [CMakeFiles/BloomBloomier.dir/all] Error 2
make[1]: *** [CMakeFiles/BloomBloomier.dir/rule] Error 2
make: *** [BloomBloomier] Error 2



Here's a snippet of main.cpp

C++
#include <fstream>
#include <iostream>
#include "libs/bloomFilter/bloom_filter.hpp"
#include "libs/bloomierFilter/BloomierFilter.h"
#include <math.h>
using namespace std;

class bloomBloomier
{

public:

    void instantiate(int n, float p){

        //...


        //THIS REGION IS CAUSING THE ERROR, IT RUNS FINE IN bloomierFilterTest
        int hash = 0; int m = 10; int k = 5; int q = 24;
        map<string, int> mp; mp["abc"] = 10; mp["def"] = 20; mp["abd"] = 30;
        vector<string> keys = {"abc", "def", "abd"};
        auto bf = bloomier::BloomierFilter(hash, &mp, m, k, q);


        //...


    }


Here is BloomierFilter.h:

C++
#ifndef __BloomierFilter_H_
#define __BloomierFilter_H_

#include <map>
#include <vector>
#include <iostream>
#include <cstddef>
#include <cstring>
#include "core/util.h"
#include "core/utilEncode.h"
#include "core/bloomierHasher.h"
#include "core/orderAndMatchFinder.h"

namespace bloomier {

class BloomierFilter {
    int hashSeed;
    std::map<std::string, int>* keyMap;
    OrderAndMatchFinder* oam = NULL;
    OrderAndMatch* om = NULL;
    BloomierHasher* h = NULL;

    int m;
    int k;
    int q;
    int byteSize;

    unsigned char *table = NULL;
    // not size optimal, only for testing purposes
    int *valueTable = NULL;
public:
    BloomierFilter(int hashSeed, std::map<std::string, int>* keyMap, int m, int k, int q);
    ~BloomierFilter();
    void create(std::map<std::string, int>* keyMap, OrderAndMatchFinder* oam);
    bool get(std::string key, int& value);
    bool set(std::string key, int value);
};

}
#endif //__BloomierFilter_H_


Here is the CMakeLists.txt file (Note: This is probably where I'm having an issue, im brand new to cmake/make):

cmake_minimum_required(VERSION 3.1)
project(BloomBloomier)

# cmake -DCMAKE_BUILD_TYPE:STRING=Debug ../src
# http://www.cmake.org/Wiki/CMake_Useful_Variables#Compilers_and_Tools
set(CMAKE_CXX_FLAGS_DEBUG, ON)
set(CMAKE_CXX_COMPILER "/usr/bin/c++")
#set(CMAKE_CXX_COMPILER "/usr/bin/llvm-g++")
# http://stackoverflow.com/questions/5334095/cmake-multiarchitecture-compilation
set(CMAKE_CXX_FLAGS "-std=c++11 -m64")
# cmake -DCMAKE_OSX_ARCHITECTURES=x86_64

include_directories(/usr/local/include)
include_directories(.)
include_directories(./core)
link_directories(/usr/local/lib)
link_directories(./libs/bloomierFilter)

set(bloomier_srcs
    # bloomier filter code
    libs/bloomierFilter/BloomierFilter.cpp
    libs/bloomierFilter/core/util.cpp
    libs/bloomierFilter/core/utilEncode.cpp
    libs/bloomierFilter/core/hash.cpp
    libs/bloomierFilter/core/bloomierHasher.cpp
    libs/bloomierFilter/core/singletonFindingTweaker.cpp
    libs/bloomierFilter/core/orderAndMatchFinder.cpp
    )

add_library(bl ${bloomier_srcs})



set(SOURCE_FILES main.cpp)


add_executable(BloomBloomier ${SOURCE_FILES})


Here is the file that the snippet of code runs fine in:

C++
#include <limits.h>
#include <time.h>
#include <gtest/gtest.h>
#include <list>
#include <map>
#include <string>
#include "BloomierFilter.h"
#include "util.h"

using namespace std;

class QuickTest : public testing::Test {
//...
};

class BloomierFilterTest : public QuickTest {
//...
};

TEST_F(BloomierFilterTest, simpleGetTest) {


    //THIS SNIPPET RUNS FINE WHEN BUILDING THIS PROJECT
    int hash = 0; int m = 10; int k = 5; int q = 24;
    map<string, int> mp; mp["abc"] = 10; mp["def"] = 20; mp["abd"] = 30;
    vector<string> keys = {"abc", "def", "abd"};
    auto bf = bloomier::BloomierFilter(hash, &mp, m, k, q);

    //...
}

TEST_F(BloomierFilterTest, simpleSetTest) {
    //...
}

And finally here is the cmakelists.txt for the project that this last snippet is in:

cmake_minimum_required(VERSION 2.8)
project( bloomier )

# cmake -DCMAKE_BUILD_TYPE:STRING=Debug ../src
# http://www.cmake.org/Wiki/CMake_Useful_Variables#Compilers_and_Tools
set(CMAKE_CXX_FLAGS_DEBUG, ON)
set(CMAKE_CXX_COMPILER "/usr/bin/c++")
#set(CMAKE_CXX_COMPILER "/usr/bin/llvm-g++")
# http://stackoverflow.com/questions/5334095/cmake-multiarchitecture-compilation
set(CMAKE_CXX_FLAGS "-std=c++11 -m64")
# cmake -DCMAKE_OSX_ARCHITECTURES=x86_64

include_directories(/usr/local/include)
include_directories(.)
include_directories(./core)
link_directories(/usr/local/lib)

set(bloomier_srcs
    main.cpp

    # bloomier filter code
    BloomierFilter.cpp
    core/util.cpp
    core/utilEncode.cpp
    core/hash.cpp
    core/bloomierHasher.cpp
    core/singletonFindingTweaker.cpp
    core/orderAndMatchFinder.cpp

    # test code
    test/testutil.cc
    test/testUtilEncode.cc
    test/testHash.cc
    test/testBloomierHasher.cc
    test/testSingletonFindingTweaker.cc
    test/testOrderAndMatchFinder.cc
    test/testBloomierFilter.cc
    )

add_executable(bl ${bloomier_srcs})
target_link_libraries(bl gtest.a)


I've been working on this for days and I would REALLY appreciate some help.
Posted
Comments
Andreas Gieriet 29-Mar-15 14:34pm    
What is the linker command line?
It seems that you do not link the library or the object file that contains the missing functions (at least the constructor and destructor of BloomierFilter).
Cheers
Andi
Member 11564768 29-Mar-15 15:59pm    
Hi Andi, thanks so much for the reply. I actually just put the project on github (https://github.com/CSNoyes/BloomBloomierScanner) so you can see the actual files. Could you recommend to me how you would link the library's using the CMake build system? I'm rather new.
Thanks,
Charlies
Andreas Gieriet 29-Mar-15 16:25pm    
You expect too much! This is Quick Answer forum. I cannot take the time to download and compile your project. Sorry.
Please answer my question or wait for someone else to try to help you.
Regards
Andi
Richard MacCutchan 30-Mar-15 3:59am    
Where is the implementation of BloomierFilter?

The normal cause of such issues is, that you havent included the implementation _OR_ you havent implemented the same interface as you declared in your header.

You must fiddle the diff between header and implementation out. Is this function only declared, but NOT implemented. A typo?

C++
BloomierFilter(int hashSeed, std::map<std::string,>* keyMap, int m, int k, int q);
 
Share this answer
 
Your error is likely caused by this piece of code:
C#
add_library(bl ${bloomier_srcs}) #make a library object (.so or .a) with these sources



set(SOURCE_FILES main.cpp) #set main.cpp into SOURCE_FILES


add_executable(BloomBloomier ${SOURCE_FILES}) #make executable with SOURCE_FILES



You're adding the bloomier filter sources to an external library and never referencing that in the executable. You have to tell cmake to make the linkage between those two.

You do that with target_link_libraries()[^].
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900