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}
修改说明
- 合并X11头文件路径到CXXFLAGS:Make的C++隐式编译规则会自动使用
CXXFLAGS变量,将-I/opt/X11/include加入后,编译.cc文件时就能找到X11头文件,解决'X11/Xlib.h' file not found错误。 - 移除重复参数:
-std=c++14已在CXXFLAGS中定义,无需在链接阶段重复指定;X11FLAGS仅包含头文件路径,链接阶段不需要,直接移除。 - 正确处理依赖文件:将
-include $(DEPENDS)放在全局位置,Make会自动包含生成的.d依赖文件,确保头文件变化时能重新编译对应源文件,避免在链接命令中错误使用-include。
内容的提问来源于stack exchange,提问作者ajsdiubfaoishd
相关产品推荐
相关产品推荐

