Ujjwal Aryan
Ujjwal Aryan

Reputation: 4077

CMAKE LINKING ERROR with a user-defined shared library

I am a newcomer to the world of cmake. This question came up while I was experimenting with some basic cmake configurations in C++. To be precise, following is my directory structure :

/src----

 |-> CMakeLists.txt
   |-> main.cpp
   |-> lib----
              |-> libfsystem.so
   |->filesystem----
                    |->CMakeLists.txt
                    |->listfiles.cpp
                    |->include-----
                                   |->fsystem.h

Now, the /src/filesystem/CMakeLists.txt file is like this

cmake_minimum_required(VERSION 2.8)
project(fsystem)
set(CMAKE_BUILD_TYPE Release)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/build)
find_package(Boost REQUIRED system filesystem)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(fsystem SHARED listfiles.cpp)

While, the /src/CMakeLists.txt file is like this

cmake_minimum_required(VERSION 2.8)

project(vessel_detect)

add_subdirectory(filesystem)

add_executable(main main.cpp)

set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
find_library(libpath fsystem)
MESSAGE(${libpath})
target_link_libraries(main ${libpath})
  1. The library libfsystem.so is successfully created.
  2. The library libfsystem.so is also successfully found by /src/CMakeLists.txt

However when the linking of main.cpp is done, then it gives me several undefined reference errors which should not have happened as everything has already been defined. For greater completeness, following is the content of main.cpp file

Main.cpp

#include<iostream>
#include"filesystem/include/fsystem.h"
using namespace std;
int main(void)
{
        string path ("~");
        vector<string>* output;
        output = listfiles(path);
        return 0;
}

The contents of listfiles.cpp are

listfiles.cpp

#include"fsystem.h"
using namespace boost::filesystem;
vector<string>* listfiles(int argc, char* argv[])
{
         if (argc<2)
        {
                std::cout<<"No file name provided"<<std::endl;
        }
        else
        {
                path p(argv[1]);
                vector<string>* output;
                if (exists(p))
                {
                        if(is_directory(p))
                        {
                                std::cout<<"You specified a directory"<<std::endl;
                                std::cout<<"Its contents are as follows :-"<<std::endl;
                                typedef std::vector<path> vec;
                                vec v;
                                copy(directory_iterator(p),directory_iterator(),back_inserter(v));
                                sort(v.begin(),v.end());
                                for(vec::const_iterator it(v.begin());it!=v.end();++it)
                                          output->push_back(it->filename().string());
//                                        std::cout<<it->filename()<<std::endl;
                        }
                        else if (is_regular_file(p))
                                {
                                        std::cout<<argv[1]<<"   "<<file_size(p)<<std::endl;
                                }
                                else
                                {
                                        std::cout<<"The file is neither a directory nor a regular file"<<std::endl;
                                }
                }
                else
                {
                        std::cout<<"The speicified path does not exist"<<std::endl;
                                                                                                             }             
           }
}

And finally, the fsystem.h contents are :

fsystem.h

#ifndef _fsystem_h
#define _fsystem_h
#include<iostream>
#include<string>
#include<vector>
#include"boost/filesystem.hpp"
using namespace std;
vector<string>* listfiles(string);
#endif

Could someone provide me a reason for the undefined reference errors I am getting during the linking of main.cpp ? I would also be grateful if you could provide me with a resolution of this issue.

Thanks

Upvotes: 1

Views: 1954

Answers (2)

Mark Nunberg
Mark Nunberg

Reputation: 3691

(1) For TARGET_LINK_LIBRARIES you should put the name of the target, thus:

TARGET_LINK_LIBRARIES(main fsystem)

(2) You declare listfiles as vector<string>* listfiles(string) while you define it as vector<string>* listfiles(int,char**)

Additionally you need to link with Boost per the other reply.

Upvotes: 1

user1937198
user1937198

Reputation: 5348

Your not linking boost. you need to add target_link_libraries(fsystem ${Boost_LIBRARIES}) to the end of /src/filesystem/CMakeLists.txt and include_directories(${Boost_INCLUDE_DIRS}) between the find_package and add_library.

cmake_minimum_required(VERSION 2.8)
project(fsystem)
set(CMAKE_BUILD_TYPE Release)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/build)
find_package(Boost REQUIRED system filesystem)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(${Boost_INCLUDE_DIRS})
add_library(fsystem SHARED listfiles.cpp)
target_link_libraries(fsystem ${Boost_LIBRARIES})

Upvotes: 2

Related Questions