I am really new to C++ and I am a bit confused.
I am trying to add this lib to my project (https://github.com/mrtazz/restclient-cpp).
I have installed it using Homebrew
brew tap mrtazz/oss
brew install restclient-cpp
then I tried adding the library to my CMakeLists by including and linking the Homebrew install directories.
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(POS)
set(CMAKE_CXX_STANDARD 14)
include_directories(/usr/local/include)
link_directories(/usr/local/lib)
add_library(
restclient-cpp STATIC
connection.h
helpers.h
restclient.h
version.h
)
add_executable(POS main.cpp program.cpp program.h programs/find.cpp programs/find.h tools/db.cpp tools/db.h)
target_link_libraries(POS PUBLIC restclient-cpp)
then I get this error...
CMake Error at CMakeLists.txt:16 (add_library):
Cannot find source file:
connection.h
Tried extensions .c .C .c++ .cc .cpp .cxx .cu .m .M .mm .h .hh .h++ .hm
.hpp .hxx .in .txx
CMake Error at CMakeLists.txt:16 (add_library):
No SOURCES given to target: restclient-cpp
I know something is wrong with the directories but I just cannot figure it out, I would greatly appreciate as much information as possible. I'm just trying to have some fun with this and I cannot figure out why I cannot add this simple library to my build.
Thank you.
You are trying to add header files to the add_library command. Those files need to be in a directory that you include via include_directory. You also should not put header files into the add_executable command.
To link an existing library you can call target_link_libraries.
example:
include_directories(${MY_INCLUDE_DIRS})
add_executable(main source.cpp)
target_link_libraries(main extlib)
It's probably best to find a simple CMake setup and try to use it as template.
Related
I am trying to build a simple CNN model using Pytorch C++ API ( libtorch ), but when I try to run CMake it gives me this error:
CMake Error at CMakeLists.txt:4 (add_executable):
Cannot find source file:
training_VGG.cpp
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
CMake Error: CMake can not determine linker language for target: example
CMake Error: Cannot determine link language for target "example".
----------------------------------------------------------------------------
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(Digit-Recognition-MNIST)
find_package(Torch REQUIRED)
add_executable(example training_VGG.cpp)
target_link_libraries(example "${TORCH_LIBRARIES}")
set_property(TARGET example PROPERTY CXX_STANDARD 11)
I hope anyone can help me.
I've using cmake to build my google rpc sample code. I've got
examples.proto
client.cpp
server.cpp
I use protoc command to build out .cc/.h files for both protobuf and grpc, CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
add_definitions(-std=c++11)
include_directories(.)
add_custom_target(protoFile
PRE_BUILD
COMMAND protoc --cpp_out=./ examples.proto
)
add_custom_target(protoSource
PRE_BUILD
COMMAND protoc --grpc_out=./ --plugin=protoc-gen-grpc=/usr/local/bin/grpc_cpp_plugin examples.proto
)
add_dependencies(protoSource protoFile)
add_library(protoCpp SHARED examples.grpc.pb.cc examples.pb.cc)
add_dependencies(protoCpp protoSource)
link_libraries(protoCpp protobuf grpc grpc++)
add_executable(client client.cpp)
add_executable(server server.cpp)
And then:
cmake .
-- Configuring done
CMake Error at CMakeLists.txt:15 (add_library):
Cannot find source file:
examples.grpc.pb.cc
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
CMake Error: CMake can not determine linker language for target: protoCpp
CMake Error: Cannot determine link language for target "protoCpp".
-- Generating done
Seems my "add_custom_target()" was not executed, and "ls" didn't show any files I expected. So how to make them executed? I already added "protoSource as dependency for "protoCpp" library, but didn't work.
How to solve this?
Use add_custom_target after add_executable, and the first parameter should be a target created by add_executable, in your example "client" or "server". You can't use PRE_BUILD in add_custom_target, but I'm not sure;
See also: add_custom_target documentation.
If I have .h and .cpp files in the directory src, where the .cpp files include the .h files, using these commands in CMake:
aux_source_directory(src SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
And opening that CMake file in Qt Creator, gets all the files (sources + headers) in the list of project files (the file tree on the left by default).
Now, on the other hand, if I put all the .h files in a directory include, and use this:
include_directories(include)
aux_source_directory(src SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
The header files disappear from the project files!
How can I keep the header files in that directory, and still have them listed in Qt Creator's project files?
You shouldn't use aux_source_directory() for your task. That command is for something different. Just list the source files (or put them in a variable).
You shouldn't use include_directory() for defining include directories any more. This command will just populate the -I flag of the compiler. Define a variable with the header files and add that to the executable.
In case you don't want to list every file manually, use file(GLOB ...). But be aware of the caveats mentioned frequently all over the web with using that command.
Afterwards, tell CMake to populate the -I flag only for that executable with the include directory. That way, other targets don't get polluted by includes, they shouldn't use.
set(SOURCES
src/main.cpp
src/whatever.cpp)
set(HEADERS
include/whatever.h)
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME} PUBLIC include)
I add my header files always explicit to avoid any surprise.
But on MacOS using QtCreator 4.2.0 and cmake 3.7.1 I can't reproduce your issue.
However I recommend to use following structure to know which files are within project and to trigger update of cmake's data during update of CMakeLists.txt.
In project/CMakeLists.txt:
add_subdirectory(src)
include_directory(include)
add_executable(foo ${SRC_LIST})
In project/src/CMakeLists.txt:
set(SRC_LIST
${SRC_LIST}
${CMAKE_CURRENT_SOURCE_DIR}/a.cpp
${CMAKE_CURRENT_SOURCE_DIR}/b.cpp
PARENT_SCOPE
)
I'm trying to link in a pre-compiled shared library file called libtest-lib.so. This is what I have at the bottom of my CMakeLists.txt:
link_directories("/projectspath/LinkTest/TestLib/app/build/intermediates/cmake/debug/obj/armeabi-v7a")
add_library(testlib libtest-lib.so)
target_link_libraries(testlib libtest-lib.so)
As above, I get the following error:
CMake Error at CMakeLists.txt:49 (add_library):
Cannot find source file:
libtest-lib.so
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
CMake Error: CMake can not determine linker language for target: testlib
If I comment out the add_library line, I get the following:
CMake Error at CMakeLists.txt:51 (target_link_libraries):
Cannot specify link libraries for target "testlib" which is not built by this project.
It seems that source files (.c, cpp, etc) are absolutely required when linking in a library. But how do I link in an .so file? The docs say the following about target_link_libraries():
The named must have been created in the current directory by a command such as add_executable() or add_library().
If I substitute add_library() with add_executable() I get the same error. What is the proper way to link an .so file in CMake?
I think that what you want is to import a library for CMake:
add_library(testlib SHARED IMPORTED)
set_property(TARGET testlib PROPERTY IMPORTED_LOCATION "/projectspath/LinkTest/TestLib/app/build/intermediates/cmake/debug/obj/armeabi-v7a/libtest-lib.so")
See https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/Exporting-and-Importing-Targets for more information
add_library creates a new library.
Instead you want to link your library to some other target.
Let's say
add_executable(main main.cpp)
target_link_libraries(main libtest-lib)
This should already work.
You should have:
link_directories("/projectspath/LinkTest/TestLib/app/build/intermediates/cmake/debug/obj/armeabi-v7a")
set(MY_SOURCES mylib.cpp)
add_library(testlib ${MY_SOURCES})
target_link_libraries(testlib libtest-lib)
which means that you should specify the sources of YOUR library as second argument to add_library() or add_executable() and not the library that is already compiled.
You need your sources because generally you build something (a library or an executable) that requires linking to some library that already exist.
Otherwise, what would you build? Nothing? And link the library to what? Who would be the consumer of that library?
I found another workaround, to mention path where the library is present while linking lib to the executable file.
INCLUDE_DIRECTORIES(/path/to/headers)
ADD_EXECUTABLE(TARGET target.c)
TARGET_LINK_LIBRARIES(TARGET_FILE "-L/path/to/shared/library" SHARED_LIB_name)
Which is indirect including library search path flag. One might also have to link the location of header files while using the library.
The proper way to do this is:
target_link_libraries(native-lib "/projectspath/LinkTest/TestLib/app/build/intermediates/cmake/debug/obj/${ANDROID_ABI}/libtest-lib.so")
I have a library with several source files under several directories. I want to write a cmake in a way that it add all of them to project without asking to writ them separately.
I am using this line in my cmake:
FILE(GLOB_RECURSE ALL_Lib_CPP_SRCS src/Library/ *.cpp)
add_library(MyLibrary STATIC ALL_Lib_CPP_SRCS)
but generate msvc project doesn't have all files included and I am getting this message when I am running cmake:
CMake Error at CMakeLists.txt:49 (add_library):
Cannot find source file:
ALL_Lib_CPP_SRCS
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp .hxx .in .txx
What is the problem with this cmake?
It should be:
FILE(GLOB_RECURSE ALL_Lib_CPP_SRCS "src/Library/*.cpp")
add_library(MyLibrary STATIC ${ALL_Lib_CPP_SRCS})
In my opinion, it's better that you defined manually the sources:
set (_SOURCES source3.cpp source2.cpp source1.cpp main.cpp)
# now use ${_SOURCES}
this way, you can know the exact order of compilation...sometimes the order is important
The correct syntax according to the manual is:
file(GLOB_RECURSE variable [RELATIVE path] [FOLLOW_SYMLINKS] [globbing expressions]...)
I suspect you're either missing RELATIVE:
FILE(GLOB_RECURSE ALL_Lib_CPP_SRCS RELATIVE "src/Library/" "*.cpp")
Or you have an extra space in the globbing expression:
FILE(GLOB_RECURSE ALL_Lib_CPP_SRCS "src/Library/*.cpp")
I suspect the second option above is what you want. The quotes are optional, but I would recommend their use, as it makes the line easier to read IMO.
The second issue is that you need a ${} when you reference the variable:
add_library(MyLibrary STATIC ${ALL_Lib_CPP_SRCS})