我在CLion中的FreeBSD 11上使用CMake并拥有以下CMakeLists.txt:
cmake_minimum_required(VERSION 3.7)
project(owm)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp owm.cpp owm.h)
add_executable(owm ${SOURCE_FILES})
set(LIBS ${LIBS})
find_package(X11 REQUIRED)
if (X11_FOUND)
include_directories(${X11_INCLUDE_DIR})
link_libraries(${X11_LIBRARIES})
endif(X11_FOUND)
file(GLOB MY_PUBLIC_HEADERS
"test/*"
)
file(COPY ${MY_PUBLIC_HEADERS} DESTINATION test)
这似乎工作正常,但是在编译项目时,我得到以下内容:
/usr/local/bin/cmake --build /home/cory/projects/owm/cmake-build-debug --target all -- -j 12
Scanning dependencies of target owm
[ 33%] Building CXX object CMakeFiles/owm.dir/owm.cpp.o
[ 66%] Linking CXX executable owm
CMakeFiles/owm.dir/owm.cpp.o: In function `owm::Create(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)':
/home/cory/projects/owm/owm.cpp:20: undefined reference to `XOpenDisplay'
/home/cory/projects/owm/owm.cpp:22: undefined reference to `XDisplayName'
CMakeFiles/owm.dir/owm.cpp.o: In function `owm::owm(_XDisplay*)':
/home/cory/projects/owm/owm.cpp:31: undefined reference to `XInternAtom'
/home/cory/projects/owm/owm.cpp:32: undefined reference to `XInternAtom'
CMakeFiles/owm.dir/owm.cpp.o: In function `owm::~owm()':
/home/cory/projects/owm/owm.cpp:37: undefined reference to `XCloseDisplay'
c++: error: linker command failed with exit code 1 (use -v to see invocation)
gmake[2]: *** [CMakeFiles/owm.dir/build.make:121: owm] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/owm.dir/all] Error 2
gmake: *** [Makefile:84: all] Error 2
我不确定这是否相关,但message(FATAL_ERROR ${X11_LIBRARIES})
会返回:
/usr/local/lib/libSM.so/usr/local/lib/libICE.so/usr/local/lib/libX11.so/usr/local/lib/libXext.so
message(FATAL_ERROR ${X11_INCLUDE_DIR})
返回:
/usr/local/include
在违规文件中我有:
#include "owm.h"
extern "C" {
#include <X11/Xlib.h>
#include <X11/Xutil.h>
}
#include <iostream>
#include <cstring>
#include <algorithm>
template <typename T>
T* CHECK_NOTNULL(T* t) {
if (t == NULL) {
}
return (t);
}
std::unique_ptr<owm> owm::Create(const std::string& display_str) {
const char* display_c_str = (display_str.empty() ? nullptr : display_str.c_str());
Display* display = XOpenDisplay(display_c_str);
if (display == nullptr) {
std::cout << "Failed to open X display " << XDisplayName(display_c_str);
return (nullptr);
}
return (std::unique_ptr<owm>(new owm(display)));
}
owm::owm(Display *display)
: _display(CHECK_NOTNULL(display)),
_root(DefaultRootWindow(_display)),
WM_PROTOCOLS(XInternAtom(_display, "WM_PROTOCOLS", false)),
WM_DELETE_WINDOW(XInternAtom(_display, "WM_DELETE_WINDOW", false)) {
}
owm::~owm() {
XCloseDisplay(_display);
}
void owm::Run() {
}
答案 0 :(得分:2)
命令link_libraries
仅影响其他可执行文件/库。来自documentation:
指定在以后通过
add_executable()
或add_library()
等命令链接当前目录或更低版本中创建的任何目标时要使用的库或标志。
所以你需要:
在 link_libraries
或
add_executable
改为使用target_link_libraries
(这是首选方式)