X11在FreeBSD 11上包含c ++通过CLION的问题?

时间:2017-03-15 09:00:11

标签: cmake x11 clion

我在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() {

}

1 个答案:

答案 0 :(得分:2)

命令link_libraries仅影响其他可执行文件/库。来自documentation

  

指定在以后通过add_executable()add_library()等命令链接当前目录或更低版本中创建的任何目标时要使用的库或标志。

所以你需要:

  • link_libraries

  • 之前使用add_executable
  • 改为使用target_link_libraries(这是首选方式)