X11 在 FreeBSD 11 上通过 CLion 包含 c++ 的问题?
X11 Include Issues With c++ Via CLion On FreeBSD 11?
我在 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})
returns:
/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})
returns:
/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() {
}
命令 link_libraries
仅影响 进一步 executables/libraries。来自 documentation:
Specify libraries or flags to use when linking any targets created later in the current directory or below by commands such as add_executable()
or add_library()
.
因此您需要:
在add_executable
或
之前使用link_libraries
改用target_link_libraries
(这是首选方式)
我在 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})
returns:
/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})
returns:
/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() {
}
命令 link_libraries
仅影响 进一步 executables/libraries。来自 documentation:
Specify libraries or flags to use when linking any targets created later in the current directory or below by commands such as
add_executable()
oradd_library()
.
因此您需要:
在
add_executable
或 之前使用改用
target_link_libraries
(这是首选方式)
link_libraries