You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS下XQuartz环境X11项目Makefile无法找到<X11/Xlib.h>

修复macOS X11项目Makefile编译问题

问题背景

在macOS上使用XQuartz(已确认/opt/X11目录完整,xeyes可正常运行)开发X11图形项目,包含多个.cc文件,编写Makefile编译时出现头文件找不到的错误,手动编译命令可正常运行。

当前目录结构

项目目录结构

当前Makefile内容

CXX=g++
CXXFLAGS=-std=c++14 -Wall -g -MMD
EXEC=main
CCFILES=$(wildcard *.cc)
OBJECTS=${CCFILES:.cc=.o}
DEPENDS=${CCFILES:.cc=.d}
X11FLAGS=-I/opt/X11/include
X11LIBS=-L/opt/X11/lib -lX11

${EXEC}: ${OBJECTS}
    ${CXX} -std=c++14 -o ${EXEC} ${X11FLAGS} ${OBJECTS} ${X11LIBS} -include ${DEPENDS} 

make -n预执行输出

g++ -std=c++14 -Wall -g -MMD   -c -o gfx_demo_main.o gfx_demo_main.cc
g++ -std=c++14 -Wall -g -MMD   -c -o gfx_demo_window.o gfx_demo_window.cc
g++ -std=c++14 -o main -I/opt/X11/include gfx_demo_main.o gfx_demo_window.o -L/opt/X11/lib -lX11 -include gfx_demo_main.d gfx_demo_window.d 

编译错误信息

g++ -std=c++14 -Wall -g -MMD   -c -o gfx_demo_main.o gfx_demo_main.cc
In file included from gfx_demo_main.cc:5:
./gfx_demo_window.h:7:10: fatal error: 'X11/Xlib.h' file not found
#include <X11/Xlib.h>
         ^~~~~~~~~~~~
1 error generated.

可行的手动编译命令

g++ -std=c++14 -I/opt/X11/include gfx_demo_main.cc gfx_demo_window.cc -L/opt/X11/lib -lX11

项目代码文件

gfx_demo_main.cc

#include <iostream>
#include "gfx_demo_window.h"

using namespace std;

int main() {
  Xwindow w;

  for (int i = Xwindow::White ; i <= Xwindow::Blue; i++) {
    w.fillRectangle(50 * i, 200, 50, 250, i);
  }

  w.drawString(50, 50, "Hello!");

  w.drawString(50, 100, "ABCD");

  w.drawString(50, 150, "Hello!");

  Xwindow w2(199, 199);
  w2.drawString(50, 100, "ABCD");

  char c;
  cin >> c;
}

gfx_demo_window.cc

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <iostream>
#include <cstdlib>
#include <string>
#include <unistd.h>
#include "gfx_demo_window.h"

using namespace std;

Xwindow::Xwindow(int width, int height) {
  d = XOpenDisplay(NULL);
  if (d == NULL) {
    cerr << "Cannot open display" << endl;
    exit(1);
  }
  s = DefaultScreen(d);
  w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, width, height, 1,
                          BlackPixel(d, s), WhitePixel(d, s));
  XSelectInput(d, w, ExposureMask | KeyPressMask);
  XMapRaised(d, w);

  Pixmap pix = XCreatePixmap(d,w,width,
        height,DefaultDepth(d,DefaultScreen(d)));
  gc = XCreateGC(d, pix, 0,(XGCValues *)0);

  XFlush(d);
  XFlush(d);

  // Set up colours.
  XColor xcolour;
  Colormap cmap;
  char color_vals[7][10]={"white", "black", "red", "green", "blue"};

  cmap=DefaultColormap(d,DefaultScreen(d));
  for(int i=0; i < 5; ++i) {
      XParseColor(d,cmap,color_vals[i],&xcolour);
      XAllocColor(d,cmap,&xcolour);
      colours[i]=xcolour.pixel;
  }

  XSetForeground(d,gc,colours[Black]);

  // Make window non-resizeable.
  XSizeHints hints;
  hints.flags = (USPosition | PSize | PMinSize | PMaxSize );
  hints.height = hints.base_height = hints.min_height = hints.max_height = height;
  hints.width = hints.base_width = hints.min_width = hints.max_width = width;
  XSetNormalHints(d, w, &hints);

  XSynchronize(d,True);

  usleep(1000);
}

Xwindow::~Xwindow() {
  XFreeGC(d, gc);
  XCloseDisplay(d);
}

void Xwindow::fillRectangle(int x, int y, int width, int height, int colour) {
  XSetForeground(d, gc, colours[colour]);
  XFillRectangle(d, w, gc, x, y, width, height);
  XSetForeground(d, gc, colours[Black]);
}

void Xwindow::drawString(int x, int y, string msg) {
  XDrawString(d, w, DefaultGC(d, s), x, y, msg.c_str(), msg.length());
}

gfx_demo_window.h

#ifndef __WINDOW_H__
#define __WINDOW_H__
#include <X11/Xlib.h>
#include <iostream>
#include <string>

class Xwindow {
  Display *d;
  Window w;
  int s;
  GC gc;
  unsigned long colours[10];

 public:
  Xwindow(int width=500, int height=500);  // Constructor; displays the window.
  ~Xwindow();                              // Destructor; destroys the window.
  Xwindow(const Xwindow&) = delete;
  Xwindow &operator=(const Xwindow&) = delete;

  enum {White=0, Black, Red, Green, Blue}; // Available colours.

  // Draws a rectangle
  void fillRectangle(int x, int y, int width, int height, int colour=Black);

  // Draws a string
  void drawString(int x, int y, std::string msg);
};

#endif

修复后的Makefile及说明

修复后的Makefile

CXX=g++
CXXFLAGS=-std=c++14 -Wall -g -MMD -I/opt/X11/include
EXEC=main
CCFILES=$(wildcard *.cc)
OBJECTS=${CCFILES:.cc=.o}
DEPENDS=${CCFILES:.cc=.d}
X11LIBS=-L/opt/X11/lib -lX11

-include $(DEPENDS)

${EXEC}: ${OBJECTS}
    ${CXX} -o ${EXEC} ${OBJECTS} ${X11LIBS}

修改说明

  1. 合并X11头文件路径到CXXFLAGS:Make的C++隐式编译规则会自动使用CXXFLAGS变量,将-I/opt/X11/include加入后,编译.cc文件时就能找到X11头文件,解决'X11/Xlib.h' file not found错误。
  2. 移除重复参数:-std=c++14已在CXXFLAGS中定义,无需在链接阶段重复指定;X11FLAGS仅包含头文件路径,链接阶段不需要,直接移除。
  3. 正确处理依赖文件:将-include $(DEPENDS)放在全局位置,Make会自动包含生成的.d依赖文件,确保头文件变化时能重新编译对应源文件,避免在链接命令中错误使用-include。

内容的提问来源于stack exchange,提问作者ajsdiubfaoishd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 00:39:52