This question already has answers here:
Understanding "requests linking to directory" cmake warning
(1 answer)
CMake link to external library
(6 answers)
Closed 10 months ago.
I am making an anpr algorithm that requires tesseract to decode the image to text. When running cmake .. inside my build dir, I get a warning saying:
┌──(user㉿MacBookArch)-[~/dev/anpr/build]
└─$ cmake ..
-- Configuring done
CMake Warning at CMakeLists.txt:15 (target_link_libraries):
Target "main" requests linking to directory
"/home/user/dev/anpr/build/libs/leptonica". Targets may link only to
libraries. CMake is dropping the item.
CMake Warning at CMakeLists.txt:16 (target_link_libraries):
Target "main" requests linking to directory
"/home/user/dev/anpr/build/libs/tesseract". Targets may link only to
libraries. CMake is dropping the item.
-- Generating done
-- Build files have been written to: /home/user/dev/anpr/build
This leads me into the thoughts that I have made something wrong. I have copied the repos for leptonica and tesseract into the libs directory for portability.
This is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.2.2)
project( ANPR )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/include )
include_directories(${PROJECT_SOURCE_DIR}/libs/tesseract/include)
include_directories(${PROJECT_SOURCE_DIR}/libs/leptonica/include)
link_directories(${PROJECT_SOURCE_DIR}/libs/tesseract)
link_directories(${PROJECT_SOURCE_DIR}/libs/leptonica)
add_executable( main src/main.cpp )
target_link_libraries( main ${OpenCV_LIBS} )
target_link_libraries( main ${CMAKE_CURRENT_BINARY_DIR}/libs/leptonica)
target_link_libraries( main ${CMAKE_CURRENT_BINARY_DIR}/libs/tesseract)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/samples/001.jpg
${CMAKE_CURRENT_BINARY_DIR}/samples/001.jpg
COPYONLY
)
and this is my project structure:
.
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── LeptonicaTargets.cmake
│ ├── libs
│ ├── main
│ ├── Makefile
│ └── samples
├── CMakeLists.txt
...
├── include
│ └── main.hpp
├── libs
│ ├── leptonica
│ └── tesseract
...
├── samples
│ └── 001.jpg
└── src
└── main.cpp
The contents of the build dir is auto generated with cmake.
make command inside the build dir goes fine without errors even after make clean:
┌──(user㉿MacBookArch)-[~/dev/anpr/build]
└─$ make
[ 50%] Building CXX object CMakeFiles/main.dir/src/main.cpp.o
[100%] Linking CXX executable main
[100%] Built target main
How can I resolve this warning? I am open to all improvements, thank you!
I have a problem building my Qt5 project via cmake.
I run the command cmake .. && make from the directory build and I receive the following error:
/usr/bin/ld: cannot find -lengine-lib
collect2: error: ld returned 1 exit status
make[2]: *** [src/CMakeFiles/blacklist-engine-cli.dir/build.make:102: src/blacklist-engine-cli] Error 1
make[1]: *** [CMakeFiles/Makefile2:117: src/CMakeFiles/blacklist-engine-cli.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
I have searched this topic briefly, however when I ran this project without Qt5Sql, using only Qt5Core I have no problem at all building the project. In order to build the project without Qt5Sql I just have to remove the db folder, and delete lines referring to that in my other CMakeLists.txt files. My question is:
Why does it work if I want to include only Qt5Core, and why does it not work when I also include Qt5Sql? What am I doing wrong including Qt5Sql?
Please do not include answers related to QtCreator, or Qt installation errors. I have checked my Qt installation folder, and I have Qt5Core and Qt5Sql on the same directory level installed.
I am using Ubuntu 20.04, cmake version 3.16.3, Qt version 5.12.8
ls /usr/lib/x86_64-linux-gnu/cmake
Qt5 Qt5Core Qt5Gui Qt5OpenGL Qt5PrintSupport Qt5Test Qt5Xml
Qt5Concurrent Qt5DBus Qt5Network Qt5OpenGLExtensions Qt5Sql Qt5Widgets
I have the following structure in my project:
root
├── CMakeModules
│ └── Qt.cmake
├── build
├── src
│ ├── db
│ │ ├── dbmanager.cpp
│ │ ├── dbmanager.h
│ │ └── CMakeLists.txt
│ ├── engine
│ │ ├── scanner.cpp
│ │ ├── scanner.h
│ │ └── CMakeLists.txt
│ ├── CMakeLists.txt
│ └── main.cpp
└── CMakeLists.txt
CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(blacklist-engine)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMakeModules)
add_subdirectory(src)
CMakeModules/Qt.cmake:
set(CMAKE_AUTOMOC ON)
find_package(Qt5 REQUIRED COMPONENTS Core Sql)
src/CMakeLists.txt:
include(Qt)
add_subdirectory(
db
engine
)
add_executable(blacklist-engine-cli main.cpp)
target_link_libraries(
blacklist-engine-cli
Qt5::Core
Qt5::Sql
engine-lib
db-lib
)
src/main.cpp:
#include <QtCore>
#include "db/dbmanager.h"
#include "engine/scanner.h"
...
src/db/CMakeLists.txt (updated):
set (db-lib-source
dbmanager.h
dbmanager.cpp
)
add_library(db-lib ${db-lib-source})
target_link_libraries(
db-lib
Qt5::Sql
)
src/db/dbmanager.h:
#include <QtSql/QSqlDatabase>
...
src/db/dbmanager.cpp:
#include "dbmanager.h"
#include <QtSql/QSqlQuery>
...
src/engine/CMakeLists.txt:
set(engine-lib-source
scanner.h
scanner.cpp
)
add_library(engine-lib ${engine-lib-source})
src/engine/scanner.h:
#include <QtCore>
...
src/engine/scanner.cpp:
#include "scanner.h"
...
The reason for the error is because engine-lib is never built, and its CMake file is never even processed. The offending line in your CMake file is this one:
add_subdirectory(
db
engine
)
When using add_subdirectory in this manner, the second argument becomes the binary directory for the generated content related to db. As a result, you may notice that CMake placed some build artifacts in your src/engine directory, which is probably not what you want.
To fix this, you must call add_subdirectory consecutive times for including multiple sub-directories.
add_subdirectory(db)
add_subdirectory(engine)
I have a simple c++ project which includes eigen. I'm able to compile the project on my own machine but having trouble to compile it to webassembly with emscripten.
Project structure:
.
├── CMakeLists.txt
├── include
│ └── HelloWasm
│ └── my_lib.h
└── src
├── main.cpp
└── my_lib.cpp
File contents:
CMakeLists.txt
cmake_minimum_required( VERSION 3.0 )
project( HelloWasm )
# flags
# include files
include_directories( ./include .include/HelloWasm ./src )
# target
add_executable( HelloWasm ./src/main.cpp ./src/my_lib.cpp )
# 3rd party libs
find_package(Eigen3 REQUIRED NO_MODULE)
include_directories(${EIGEN3_INCLUDE_DIR})
include/HelloWasm/my_lib.h
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using Eigen::MatrixXd;
class MyLib
{
private:
protected:
public:
MyLib()
{
}
~MyLib()
{
}
void eigen_test();
};
src/main.cpp
#include <iostream>
#include "HelloWasm/my_lib.h"
using namespace std;
int main()
{
MyLib my_lib;
my_lib.eigen_test();
}
src/my_lib.cpp
#include "HelloWasm/my_lib.h"
void MyLib::eigen_test()
{
MatrixXd m(2, 2);
m(0, 0) = 3;
m(1, 0) = 2.5;
m(0, 1) = -1;
m(1, 1) = m(1, 0) + m(0, 1);
cout << '\n'
<< m << endl;
}
Compiling the project successfully locally:
mkdir build && cd build
cmake ..
make
➜ ./HelloWasm
3 -1
2.5 1.5
Errors when trying to compile to webassemply
(I tried following the steps provided in the emscripten docs)
mkdir build && cd build
cmake ..
emcmake cmake ..
output:
configure: cmake .. -DCMAKE_TOOLCHAIN_FILE=/Users/me/programming/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR="/Users/me/programming/emsdk/node/12.9.1_64bit/bin/node"
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:
CMAKE_TOOLCHAIN_FILE
-- Build files have been written to: /Users/me/programming/sandbox/cpp_sandbox/so_question_project/build
Now running make:
➜ emmake make
make: make
Scanning dependencies of target HelloWasm
[ 33%] Building CXX object CMakeFiles/HelloWasm.dir/src/main.cpp.o
[ 66%] Building CXX object CMakeFiles/HelloWasm.dir/src/my_lib.cpp.o
[100%] Linking CXX executable HelloWasm
[100%] Built target HelloWasm
Obviously that did not create a .wasm file...
Doing the following:
em++ CMakeFiles/HelloWasm.dir/src/main.cpp.o CMakeFiles/HelloWasm.dir/src/my_lib.cpp.o -o helloWasm.js
output:
em++: warning: CMakeFiles/HelloWasm.dir/src/main.cpp.o is not a valid input file [-Winvalid-input]
em++: warning: CMakeFiles/HelloWasm.dir/src/my_lib.cpp.o is not a valid input file [-Winvalid-input]
em++: error: no input files
note that input files without a known suffix are ignored, make sure your input files end with one of: ('.c', '.i', '.cpp', '.cxx', '.cc', '.c++', '.CPP', '.CXX', '.C', '.CC', '.C++', '.ii', '.m', '.mi', '.mm', '.mii', '/dev/null', '.bc', '.o', '.obj', '.lo', '.dylib', '.so', '.a', '.ll', '.h', '.hxx', '.hpp', '.hh', '.H', '.HXX', '.HPP', '.HH')
What am I missing here...?
Change:
em++ CMakeFiles/HelloWasm.dir/src/main.cpp.o CMakeFiles/HelloWasm.dir/src/my_lib.cpp.o -o helloWasm.js
To:
em++ CMakeFiles/HelloWasm.dir/src/main.cpp.o CMakeFiles/HelloWasm.dir/src/my_lib.cpp -o helloWasm.js
Emscripten can't compile my_lib.cpp.o because it's already compiled to machine code (it's an object file). You have to use a .cpp file, not .cpp.o.
I have a suggestion for you.
First, you can put your lib files (my_lib.h and my_lib.cpp) on same directory.
Second, you can create a folder for your applications (HelloWasm) and put your executable codes (main.cpp) in this folder.
Finally, you can create CMakeLists.txt file for each folder.
This is your new directory tree:
.
├── CMakeLists.txt
├── Applications
│ └── HelloWasm
│ ├── CMakeLists.txt
│ └── main.cpp
└── Libraries
├── CMakeLists.txt
├── my_lib.h
└── my_lib.cpp
CMakeLists.txt (the first one) :
cmake_minimum_required(VERSION 3.0)
project(LIBRARYANDAPPS)
#This function is starting build and looking all folders.
function( start_build )
file( GLOB_RECURSE components "${CMAKE_SOURCE_DIR}/*/CMakeLists.txt" )
foreach( component ${components} )
get_filename_component( path ${component} PATH )
add_subdirectory( ${path} )
endforeach( )
endfunction( )
start_build()
CMakeLists.txt (for HelloWasm):
#You can add Emscripten flags like this.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
-std=c++11 --bind \
-s USE_WEBGL2=1 -s FULL_ES3=1 --memory-init-file 0")
find_package(Eigen3 REQUIRED NO_MODULE)
include_directories(${EIGEN3_INCLUDE_DIR})
include_directories("${CMAKE_SOURCE_DIR}/Libraries")
ADD_EXECUTABLE(HelloWasm main.cpp)
TARGET_LINK_LIBRARIES(HelloWasm MyLib Eigen)
CMakeLists.txt (for Library):
find_package(Eigen3 REQUIRED NO_MODULE)
include_directories(${EIGEN3_INCLUDE_DIR})
ADD_LIBRARY(MyLib STATIC my_lib.cpp my_lib.h)
TARGET_LINK_LIBRARIES(MyLib Eigen)
With these edits, you can create bigger projects, libraries. And I think more useful like this.
This question already has answers here:
Linking Rust application with a dynamic library not in the runtime linker search path
(3 answers)
How do I specify the linker path in Rust?
(3 answers)
Where should I place a static library so I can link it with a Rust program?
(3 answers)
Closed 2 years ago.
I have written a C++ library with a C wrapper and want to call those functions from my Rust project. However, when I try to link my Rust project to the C library, I get a long error with the note
note: /usr/bin/ld: cannot find -l../cpp_library/build/libdisplay.so
I have tried passing an absolute path to the library and received a similar error.
My combined project has the following directory and contents
├── cpp_library
│ ├── CMakeLists.txt
│ ├── include
│ │ └── display.h
│ └── src
│ ├── display.cpp
│ └── main.cpp
└── rust_project
├── build.rs
├── Cargo.lock
├── Cargo.toml
├── src
└── main.rs
CMakeLists.txt
cmake_minimum_required(VERSION 3.1.0)
project(directory_test)
set(CMAKE_BUILD_TYPE Release)
#Bring the headers into the project
include_directories(include)
set(SOURCES "src/display.cpp")
#Generate the shared library from the sources
add_library(display SHARED ${SOURCES})
add_executable(display_test "src/main.cpp" ${SOURCES})
display.h
extern "C" {
void display();
}
display.cpp
#include <iostream>
#include "display.h"
void display(){
std::cout << "A C++ println" << std::endl;
}
main.cpp
#include "display.h"
int main() {
display();
}
build.rs
fn main() {
println!("cargo:rustc-link-search=../cpp_library/build/");
println!("cargo:rustc-link-lib=../cpp_library/build/libdisplay.so");
}
main.rs
extern {
fn display();
}
fn main() {
println!("Hello, world!");
unsafe {
display();
}
}
You can also see the project on Github.
I build the C library with
cd cpp_library
mkdir build
cd build
cmake ..
make
When I build the Rust project, I get the error shown above.
How am I supposed to link the C library to the Rust project?
Update 1
The posts How do I specify the linker path in Rust? and Where should I place a static library so I can link it with a Rust program? indicate how to add a directory to the library search path and link a library. I have tried these solutions, but still receive the error mentioned above.
Following the advice of Linking Rust application with a dynamic library not in the runtime linker search path, I compiled the rust project with
cargo rustc -- -C link-args='-Wl,-rpath,$ORIGIN/../../../cpp_library/build/'
but received the same error. I also tried passing an absolute path and received the same result.
I removed the redundant #[link(name = "display")], but this did not resolve the problem.
I am trying to first create a static library and then link it to an executable using CMake. My project file structure looks like this:
├── CMakeLists.txt
├── build
├── lib
│ ├── CMakeLists.txt
│ ├── build
│ ├── include
│ │ └── Point.hpp
│ └── src
│ └── Point.cpp
└── mainApp.cpp
I first build the library like so.
cmake_minimum_required(VERSION 2.8.9)
project(CAST3)
set(CMAKE_BUILD_TYPE Release)
include_directories(include)
file(GLOB SOURCES "src/*.cpp")
add_library(CAST3 STATIC ${SOURCES})
However, when i try to link the library to my executable I get an error.
This is my executable
#include"Point.hpp"
int main(int argc, char *argv[]){
Point p = Point(1,2,3);
return 0;
}
This is my CMake file to link the library to the executable.
cmake_minimum_required(VERSION 2.8.9)
project (CAST3)
set ( PROJECT_LINK_LIBS libCAST3.a )
link_directories( ${CMAKE_CURRENT_SOURCE_DIR}/lib/build)
add_executable(libtest mainApp.cpp)
target_link_libraries(libtest ${PROJECT_LINK_LIBS} )
When I run that I get the this error
/mainApp.cpp:1:9: fatal error: 'Point.hpp' file not found
#include"Point.hpp"
^~~~~~~~~~~
1 error generated.
make[2]: *** [CMakeFiles/libtest.dir/mainApp.cpp.o] Error 1
make[1]: *** [CMakeFiles/libtest.dir/all] Error 2
make: *** [all] Error 2
What am I missing?
What am I missing?
You are missing target_include_directories(CAST3 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) inside lib/CMakeLists.txt.
You are missing add_subdirectory(lib) from root CMakeLists.txt.
The set ( PROJECT_LINK_LIBS libCAST3.a ) and target_link_libraries(libtest ${PROJECT_LINK_LIBS} ) and link_directories( ${CMAKE_CURRENT_SOURCE_DIR}/lib/build) could be removed. Then you are missing just target_link_libraries(libtest PUBLIC CAST3). Cmake will automatically find the proper .a file and propagate include paths with target_link_libraries.
So your lib/CMakeLists.txt could look like this:
cmake_minimum_required(VERSION 3.0) # I would advise to update
project(CAST3)
include_directories(include)
file(GLOB sources src/*.cpp) # upper case variable names reserved for exported variables by convention
add_library(CAST3 ${sources}) # STATIC by default
target_include_directories(CAST3 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
And root CMakeLists.txt could look like this:
cmake_minimum_required(VERSION 3.0) # I would advise to update
project(CAST3)
add_subdirectory(lib)
add_executable(libtest mainApp.cpp)
target_link_libraries(libtest CAST3)