File structure under folder /home/cyan/proj
fst
| -- include
| |-- fstlib
| |-- fst_row_reader.h
| |-- fst
| |-- interface
| |-- fststore.h
|
| -- lib
|-- libfst.so
test.cc
CMakeLists.txt
fst
folder is a library I added and used in test.cc
.
test.cc
#include <iostream>
#include <fstlib/fst_row_reader.h>
class Add{
public:
double add2num(int a, double b){
return a b;
}
};
extern "C"
{
Add* test_new(){
return new Add;
}
int my_func(Add* t, int a, double b){
return t->add2num(a, b);
}
}
*Note: In my actual test.cc
I used some functions in fst
library. Here is just a sample for simplicity.
Problem
Previously, I can simply use g test.cc -fPIC -shared -o test.so
to get the .so
file. However, since I included the fst
lib, I got the following error:
In file included from /home/cyan/proj/fst/include/fstlib/fst_row_reader.h:7:0,
from read_fst.cc:1:
/home/cyan/proj/fst/include/fstlib/fst_reader.h:6:10: fatal error: fstlib/fst/interface/fststore.h: No such file or directory
#include <fstlib/fst/interface/fststore.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
My attempt:
$ g -L/home/cyan/proj/fst/lib -l:libfst.so
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text 0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
---------------------------------------------------------
$ g read_fst.cc -L /home/cyan/proj/fst/lib/libfst.so -fPIC -shared -o test.so
In file included from /home/cyan/proj/fst/include/fstlib/fst_row_reader.h:7:0,
from read_fst.cc:1:
/home/cyan/proj/fst/include/fstlib/fst_reader.h:6:10: fatal error: fstlib/fst/interface/fststore.h: No such file or directory
#include <fstlib/fst/interface/fststore.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
I also tried CMakeLists.txt
to link the fst
library as well as create a .so
file under the path /home/cyan/proj/build/lib
. But I am very new to CMake. Here is my attempt:
cmake_minimum_required(VERSION 3.0.0)
project(MY_PROJ VERSION 0.1.0)
set(mylibSRCS test.cc)
message(STATUS "Build test.so")
include_directories(${CMAKE_SOURCE_DIR}/fst/include)
link_directories(${CMAKE_SOURCE_DIR}/fst/lib)
add_library(MY_PROJ SHARED ${mylibSRCS})
set_target_properties(MY_PROJ PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
target_link_libraries(MY_PROJ ${CMAKE_SOURCE_DIR}/fst/lib/libfst.so) # link to my fst lib
target_link_libraries(MY_PROJ)
But I can't find any files under the /home/cyan/proj/build/lib
. I guess this is my CMake command issue.
Could you please help me with this problem?
CodePudding user response:
The most convenient way of using a library located on the file system imho associating the info with a imported library target which allows you to just link it using target_link_libraries
:
add_library(fst SHARED IMPORTED)
target_include_directories(fst INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/fst/include)
set_target_properties(fst PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/fst/lib/libfst.so)
...
target_link_libraries(MY_PROJ PRIVATE fst)
this way the info is easy to reuse and it listed in a single place instead of spreading it into different target properties of the linking target.
A bit more advanced, but even better would be to write fst-config.cmake
and fst-config-version.cmake
files and putting them in the "installation directory" of the library which would allow you to use find_package(fst)
to execute the logic creating the imported library which makes the library simple to reuse across multiple cmake projects, but this is beyond the scope of this answer.
The find_package
documentation provides more info about how to do this.
Btw: Note the use of CMAKE_CURRENT_SOURCE_DIR
instead of CMAKE_SOURCE_DIR
. If you're specifying absolute paths inside the directory containing the CMakeLists.txt
file containing the variable reference, since CMAKE_SOURCE_DIR
refers to the toplevel source dir which may be different, if you're including the CMakeLists.txt
using add_subdirectory
.