Getting a CMake Error: Cannot specify link libraries for target which is not built by the project - cmake

I am implementing CMake in my code but I'm getting the error
"Cannot specify link libraries for target "Qt5::Widgets" which is not built by the project".
Below are the contents of the CMakeLists.txt:
#Specify the version being used aswell as the language
cmake_minimum_required(VERSION 2.6)
#Name your project here
project(eCAD)
#Sends the -std=c++11 flag to the gcc compiler
ADD_DEFINITIONS(-std=c++11)
#This tells CMake to main.cpp and name it eCAD
add_executable(eCAD main.cpp)
#include the subdirectory containing our libs
add_subdirectory (gui)
include_directories(gui)
#include Qt directories
find_package(Qt5Widgets)
find_package(Qt5Core)
find_package(Qt5Designer)
SET(QT_USE_QTDESIGNER ON)
#link_libraries
target_link_libraries(Qt5::Widgets Qt5::Core)

In addition to the accepted answer: An important detail is to place target_link_libraries after the add_executable and find_package lines, so all linked components are known.

The first argument of target_link_libraries is the target name:
target_link_libraries(eCAD Qt5::Widgets Qt5::Core)

Also, do not confuse target name with the project name:
a command project specifies a project name, but
a target is the one created with add_executable, add_library or add_custom_target.
The error message is about the target.

Set you_lib_name before setting target_link_libraries
set(you_lib_name libname)
target_link_libraries(you_lib_name Qt5::Widgets Qt5::Core)

Related

Setting path to Clang library in CMake

I build llvm from git and want to use the libraries in a project, especially the libclang.
The "makefiles" are generated by means of CMake and for the LLVM part I found the setting LLVM_DIR to reroute the path for the llvm libraries, but for Clang I cannot find such a variable and I still see in my link line (it is a Cygwin system):
/usr/lib/libclang.dll.a /usr/lib/libclangTooling.dll.a.
Question: which environment variable do I set to get the right build Clang libraries?
The variable is Clang_DIR.
Just in case, I attach a minimalistic example of CMakeLists.txt file as well.
cmake_minimum_required(VERSION 3.12)
# Find CMake file for Clang
find_package(Clang REQUIRED)
# Add path to LLVM modules
set(CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH}
"${LLVM_CMAKE_DIR}"
)
# import LLVM CMake functions
include(AddLLVM)
include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${CLANG_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
add_definitions(${CLANG_DEFINITIONS})
add_llvm_executable(myTool main.cpp)
set_property(TARGET myTool PROPERTY CXX_STANDARD 11)
target_link_libraries(myTool PRIVATE clangTooling)

CMake library not found

I try to run the makefile that using cmake produced. It generate an error
ld: library not found for -lhello
clang: error: linker command failed with exit code 1 (use -v to see invocation)
the file directory is:
the cmakelists.txt is:
the main.c file is:
the ERROR:
I think I set the right directory. How to solve this ERROR?
CMake has a system if you want to link libraries. For many standard libraries we have cmake modules which will allow you to use the find_package command. This will set some variables for include directories and libraries. If there is no such thing for your library you can use find_path for the include files and find_library to search for a library.
Here is what you could do (untested, just out of my head):
add_executable(main main.c)
target_include_directories(
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
PUBLIC ${CMAKE_SOURCE_DIR}/include/hello
)
find_library (
HELLO_LIB
NAMES hello libhello # what to look for
HINTS "${CMAKE_SOURCE_DIR}/lib" # where to look
NO_DEFAULT_PATH # do not search system default paths
)
# check if we found the library
message(STATUS "HELLO_LIB: [${HELLO_LIB}]")
if (NOT HELLO_LIB)
message(SEND_ERROR "Did not find lib hello")
endif
target_link_libraries(main
${HELLO_LIB}
)
Use message to debug your cmake files. If you define the library in cmake as well you can link directly against the cmake target.
When your library isn't in a standard path liking /usr/lib, you should use link_directories() in your CMakeLists.txt to specify a non-standard library path which contains your library. Notice that you MUST put your link_directories() ahead of add_executable() as the following shows:
link_directories(../../lib)
add_executable(newhello main.c)
include_directories(../../include)
target_link_libraries(newhello hello)

How to correctly add path to libfiles?

My project has a dependency library in ~/SimGrid/lib directory.
How can I correctly add it to my CMakeLists.txt?
Now I try link_directories(/home/whoami/SimGrid/lib), but it doesn't help and gives:
[ 5%] Linking CXX executable CSim2Sim
/usr/bin/ld: cannot find -lsimgrid
collect2: error: ld returned 1 exit status
My full CMakeLists.txt is here:
project(CSim2Sim)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -O0")
set(SOURCE_FILES src/main.cpp)
add_executable(CSim2Sim ${SOURCE_FILES})
include_directories(/home/whoami/SimGrid/include)
link_directories(/home/whoami/SimGrid/lib)
target_link_libraries(CSim2Sim simgrid)
On Linux, linker expects library filename to be prefixed with "lib":
/home/whoami/SimGrid/lib/libsimgrid.so
If your library file has no such prefix, it cannot be found by the linker using plain library name.
As opposite, specifying full library filename in target_link_libraries call works always:
# Assume filename of the library is 'simgrid.so'
target_link_libraries(CSim2Sim /home/whoami/SimGrid/lib/simgrid.so)
In that case link_directories() call isn't needed.
link_directories only tells CMake what directories to look inside for the libraries you want to link to, not what libraries you want to link. My suggestion would be to create a file named SimGrid.cmake and add the following:
# -*- cmake -*-
set(SIMGRID_INCLUDE_DIRS
${CMAKE_SOURCE_DIR}/SimGrid/include
)
set(SIMGRID_LIBRARIES
simgrid.a
simgrid2.a # etc for the names of the actual libs you want to link
)
In your CMakeLists.txt add include(SimGrid) to pull the new file in.
Then in your CmakeLists.txt use the new variables and target_link_libraries which is the function you use to tell the linker what libraries you want to link:
include_directories(${SIMGRID_INCLUDE_DIRS})
target_link_libraries(CSim2Sim ${SIMGRID_LIBRARIES})
Of course, you could just add it all to your single CMakeLists.txt, but dividing it up is good practice to keep things manageable.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -O0")
set(SOURCE_FILES src/main.cpp)
add_executable(CSim2Sim ${SOURCE_FILES})
link_directories(${CMAKE_SOURCE_DIR}/SimGrid/lib)
include_directories(${CMAKE_SOURCE_DIR}/SimGrid/include)
set(SIMGRID_LIBRARIES
simgrid.a
simgrid2.a
)
target_link_libraries(CSim2Sim ${SIMGRID_LIBRARIES})
My recommendation is to find the libs your project depends on and link it to the target. Thus any absolut or relative path are not in the cmake file but detected while run of cmake.
See How can I find a library name of .so file?

Ogre Error In Cmake

While implementing CMake in my code I am getting an ogre error:
/usr/bin/ld: cannot find -lOGRE
My CMakeLists.txt file looks like:
#Specify the version being used aswell as the language
cmake_minimum_required(VERSION 2.6)
#Name your project here
project(eCAD)
#sets cmake to run moc when needed
set(CMAKE_AUTOMOC ON)
#find requirements of this projects
find_package(Qt5Widgets)
find_package(Qt5Core)
find_package(OGRE)
find_package(OIS)
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
#Sends the -std=c++11 flag to the gcc compiler
add_definitions(-std=c++11)
qt5_wrap_ui(Cmake_form_hdr resources/ui/mainwindow.ui)
#This tells CMake to main.cpp and name it eCAD
add_executable(eCAD main.cpp ${Cmake_form_hdr})
#include the subdirectory containing our libs
add_subdirectory (gui)
include_directories(gui)
#link_libraries
target_link_libraries(eCAD Qt5::Widgets Qt5::Core OGRE OIS)
I am new to this. Please help me out to solve the problem
The command find_package(OGRE) runs file FindOGRE.cmake and sets variables OGRE_INCLUDE_DIRS and OGRE_LIBRARIES. To link with the OGRE library, you should use these variables, e.g.
target_include_directories(eCAD PRIVATE ${OGRE_INCLUDE_DIRS})
target_link_libraries(eCAD ${OGRE_LIBRARIES})
This is same for all of the external libraries you use.

Using CMake with ifort compiler

I am using CMake 2.8.7 on a Linux machine with Intel 11.0 compilers. I am trying to use CMake for the first time as I would like to build this project on both Windows and Linux machines.
I though of using a simple approach first and used a standard Hello World example:
My src/HelloWorld.f90:
!Test helloworld in Fortran using Cmake
program hello
print *, "Hello World!"
end program hello
My main CMakeLists.txt:
# States that CMake required version must be greater than 2.8.7
cmake_minimum_required(VERSION 2.8.7)
enable_language (Fortran)
project(helloworld Fortran)
add_subdirectory(src)
SET_TARGET_PROPERTIES(helloworld PROPERTIES LINKER_LANGUAGE FORTRAN)
My src/CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.7)
# Include the directory itself as a path to include directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# For a large number of source files you can create it in a simpler way
# using file() function:
file(GLOB helloworld_SOURCES *.f90)
I still get an error which says CMAKE_FORTRAN_LINK_EXECUTABLE variable missing. I looked at Abinader's CMake tutorial#1, but haven't had success so far.
any suggestions?? Thanks in advance !
Not a direct answer, as I've never used fortran with cmake, but I can see a few issues here.
First of all: where is your target helloworld defined? project is not a target.
Secondly: where do you use helloworld_SOURCES variable?
Try a more regular way. In your src/CMakeLists.txt add line at the end of file with:
add_executable(helloworld ${helloworld_SOURCES})
Also remove SET_TARGET_PROPERTIES(helloworld PROPERTIES LINKER_LANGUAGE FORTRAN) from main one as it should not be necessary.
Last advice: try not to use file(GLOB ). It is better to define list of all files manualy.
Probably the upper-case "FORTRAN", when setting the linker language is the problem. Try writing it as "Fortran" as in the enable_language statement. CMake derives the variables it uses from the language and this causes CMake to look for CMAKE_FORTRAN_LINK_EXECUTABLE instead of CMAKE_Fortran_LINK_EXECUTABLE.
As also mentioned by Michal, the add_executable has to be added to your CMakeLists.txt.
I tested your issue with the following CMake configurations files
main CMakeLists.txt:
# States that CMake required version must be greater than 2.8.7
cmake_minimum_required(VERSION 2.8.7)
enable_language (Fortran)
project(helloworld Fortran)
add_subdirectory(src)
src/CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.7)
add_executable(helloworld HelloWorld.f90)
under Linux for following versions:
ifort (IFORT) 16.0.0.20150815
cmake version 2.8.12.2
I prefer to use cmake-gui. There you can define the ifort compiler as follows:
After definition of source code and binary folder, e.g. build, press "Configure" and select
Click "Next" and define the following compilers
Click "Finish" and "Generate".
Go to build/src folder and execute make. The helloworld executable is generated with ifort successfully and could be called here.
Hint: If ifort is already the default native compiler on your Linux computer then you don't have to specify it in cmake-gui and can go ahead with the first option "Use default native compilers".
Hope it helps.
Let's try this step-by-step:
1) Your Fortran Hello, world is OK!
src/hello.f90
!Test helloworld in Fortran using Cmake
program hello
print *, "Hello World!"
end program hello
2) Now let's write the "inner" CMakeLists.txt
src/CMakeLists.txt
add_executable(helloworld hello.f90)
set_target_properties(
helloworld
PROPERTIES
LINKER_LANGUAGE Fortran
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/build)
Here we've created an executable file, which you haven't in your question. Also, we've set its linker language to Fortran (it's case-sensitive parameter!) and the output directory for the compiled file.
3) Now we'll create the "main" CMakeLists.txt
CMakeLists.txt
# States that CMake required version must be greater than 2.8.7
cmake_minimum_required(VERSION 2.8.7)
project(helloworld Fortran)
add_subdirectory(src)
Here we've specified the src subdirectory with inner CMakeLists.txt and the compiler language - it's enough to use project() function, there's not need to use it together with enable_language().
4) Finally, let's build our code in out-of-source manner and run it!
cmake -S . -B build
cmake --build build
./build/helloworld