[C++] ”プログラミング入門” : GUIソースコード修正 Makefile, CMakeLists.txt

[M1 Mac, Big Sur 11.6.7, FLTK 1.3.8, clang 13.0.0, no IDE]

プロジェクトのディレクトリ構成は下図の通りです。

Makefile, CMakeLists.txtも載せておきます。

# コンパイラ
COMPILER = clang++
DEBUG = -g

# オプション
CPPFLAGS = $(shell fltk-config --use-gl --use-images --cxxflags ) -std=c++11 
LDFLAGS = $(shell fltk-config --use-gl --use-images --ldflags ) -lc++

# includeパス(-I)
INCLUDE = -I./include -I/opt/homebrew/Cellar/libpng/1.6.37/include -I/opt/homebrew/Cellar/fltk/1.3.8/include \
-I/opt/homebrew/Cellar/opencv/4.5.5_2/include

# ライブラリ直接パス(-l)
LIBRARYD = -lpng16 -lz -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_imgproc

# ライブラリパス(-L)
LIBRARY = -L/opt/homebrew/Cellar/jpeg/9e/lib -L/opt/homebrew/Cellar/libpng/1.6.37/lib \
-L/usr/local/lib -L/opt/homebrew/Cellar/opencv/4.5.5_2/lib

# ソースファイル
SRCDIR = ./src
SRCS = $(shell find $(SRCDIR) -type f)

# オブジェクトファイル
OBJDIR = ./obj
OBJS   = $(addprefix $(OBJDIR), $(patsubst ./src%,%,$(SRCS:.cpp=.o)))

# 実行ファイル
TARGETDIR = ./bin
TARGET = PPPGui

# プロジェクト
PROJ = PPP02

# コンパイル
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
	$(COMPILER) $(CPPFLAGS) $(INCLUDE) $(DEBUG) -o $@ -c $<

# appファイル作成関連
POSTBUILD  = fltk-config --post

# ビルド:oファイルから実行ファイルとappファイル作成
$(TARGET):$(OBJS)
	$(COMPILER) -o $(TARGETDIR)/$@ $(OBJS) $(LIBRARYD) $(LDFLAGS) $(LIBRARY)
	cp $(TARGETDIR)/$(TARGET) ./app/$(TARGET)
	cd ./app && $(POSTBUILD) $(TARGET)
	mkdir ./app/$(TARGET).app/Contents/Resources
	cp ./images/$(TARGET).icns ./app/$(TARGET).app/Contents/Resources
	plutil -insert 'CFBundleIconFile' -string $(TARGET).icns ./app/$(TARGET).app/Contents/Info.plist
	rm -f ./app/$(TARGET)

# ファイル削除
.PHONY:clean
clean:
	rm -rf $(OBJS) $(TARGETDIR)/$(TARGET) $(TARGET).app $(SRCDIR)/.DS_Store ./app/*

# CMakeからappファイル作成
.PHONY : all
all:
	rm -rf build/* $(SRCDIR)/.DS_Store
	cd /Volumes/DATA_m1/code/cpp/projects/$(PROJ)/build && cmake .. && make
	mkdir ./build/$(TARGET).app/Contents/Resources
	cp ./images/$(TARGET).icns ./build/$(TARGET).app/Contents/Resources
	plutil -replace 'CFBundleIconFile' -string "$(TARGET).icns" ./build/$(TARGET).app/Contents/Info.plist

# 自製Makefileから実行ファイルおよびappファイル作成
.PHONY:all2
all2: clean $(TARGET)

# 実行ファイルからappファイル作成(Info.plistが必要)
.PHONY : exetoapp
exetoapp:
	mkdir $(TARGETDIR)/$(TARGET)
	mkdir $(TARGETDIR)/$(TARGET)/Contents
	mkdir $(TARGETDIR)/$(TARGET)/Contents/MacOS
	mkdir $(TARGETDIR)/$(TARGET)/Contents/Resources
	cp $(TARGETDIR)/$(TARGET).exe $(TARGETDIR)/$(TARGET)/Contents/MacOS
	cp ./Info.plist $(TARGETDIR)/$(TARGET)/Contents
	cp ./images/test.icns $(TARGETDIR)/$(TARGET)/Contents/Resources
	plutil -replace 'CFBundleIconFile' -string "test.icns" $(TARGETDIR)/$(TARGET)/Contents/Info.plist
cmake_minimum_required(VERSION 3.1)

# Project
Project(PPPGui VERSION 1.0.0)
FIND_PACKAGE(FLTK REQUIRED)
FIND_PACKAGE(OpenGL REQUIRED)
find_library(COCOA Cocoa)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_VERBOSE_MAKEFILE ON)

# Info.plist
set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION})
set(MACOSX_BUNDLE_COPYRIGHT "")
set(MACOSX_BUNDLE_INFO_STRING "")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "")

# ファイル設定
file(GLOB SOURCE ./src/*.cpp ./include/*.h)

add_executable(${PROJECT_NAME}
    MACOSX_BUNDLE
    ${SOURCE}
    )

set(INCDIR ./include)
set(INCDIR ${INCDIR} /opt/homebrew/Cellar/libpng/1.6.37/include)
set(INCDIR ${INCDIR} /opt/homebrew/Cellar/fltk/1.3.8/include)
set(INCDIR ${INCDIR} /opt/homebrew/Cellar/jpeg/9e/include)
include_directories(${INCDIR})

set(LIBS dl)
set(LIBS ${LIBS} z pthread c++)
set(LIBS ${LIBS} /opt/homebrew/Cellar/fltk/1.3.8/lib/libfltk_forms.dylib)
set(LIBS ${LIBS} /opt/homebrew/Cellar/fltk/1.3.8/lib/libfltk_gl.dylib)
set(LIBS ${LIBS} /opt/homebrew/Cellar/fltk/1.3.8/lib/libfltk_images.dylib)
set(LIBS ${LIBS} /opt/homebrew/Cellar/jpeg/9e/lib/libjpeg.dylib)
set(LIBS ${LIBS} /opt/homebrew/Cellar/libpng/1.6.37/lib/libpng.dylib)
set(LIBS ${LIBS} /opt/homebrew/Cellar/fltk/1.3.8/lib/libfltk.dylib)

set(LIBDIR /opt/homebrew/Cellar/jpeg/9e/lib)
set(LIBDIR ${LIBDIR} /opt/homebrew/Cellar/libpng/1.6.37/lib)
set(LIBDIR ${LIBDIR} /opt/homebrew/Cellar/fltk/1.3.8/lib)
link_directories(${LIBDIR})

target_link_libraries(${PROJECT_NAME}
    ${FLTK}
    ${OpenGL}
    ${LIBS}
    ${COCOA})

[C++] ”プログラミング入門” : GUIソースコード修正 Gui.h, Gui.cpp他

[M1 Mac, Big Sur 11.6.7, FLTK 1.3.8, clang 13.0.0, no IDE]

Guiファイルについてはincludeのところを修正しました。

std_lib_facilities.hはストラウストラップ氏のホームページに公開しています。

#ifndef GUI_GUARD
#define GUI_GUARD

#include "Point.h"
#include <FL/Fl_Widget.H>
#include "Window.h"

namespace Graph_lib {
	
typedef void* Address;
typedef void (*Callback)(Address,Address);

template<class W> W& reference_to(Address pw)
{
	return *static_cast<W*>(pw);
}


class Widget {
public:
	Widget(Point xy, int w, int h, const string& s, Callback cb)
		:loc(xy), width(w), height(h), label(s), do_it(cb)
	{ }

	virtual void move(int dx,int dy) { hide(); pw->position(loc.x+=dx, loc.y+=dy); show(); }
	virtual void hide() { pw->hide(); }
	virtual void show() { pw->show(); }
	virtual void attach(Window&) = 0;

	Point loc;
	int width;
	int height;
	string label;
	Callback do_it;

	virtual ~Widget() { }

Gui.h, Gui.cpp 全ソースコード
Window.h, Window.cpp 全ソースコード
Simple_window.h, Point.h, main.cpp 全ソースコード

[C++] ”プログラミング入門” : GUIソースコード修正 Graph.h, Graph.cpp

[M1 Mac, Big Sur 11.6.7, FLTK 1.3.8, clang 13.0.0, no IDE]

最もボリュームがあるのがGraphファイルです。

FLTK1.1に対応した内容なのでFLTK1.3.8が使えるように書き換えました。コードがコメントアウトになっているところは復活させるかもしれないので残しておきました。

C++では自前で用意すべきerror関数がないのはご愛嬌でしょうか。

あれだけの多作家ですからコードのメンテナンスができていないところに人間味を感じます。ただ絶版にはなっていないので出版社含めちゃんとして欲しいですね。

2022/6/17追記:
ストラウストラップ氏HPのsupport code for PPP2 (tar ball)にfltk.hを含むtarがあります。fltk.hはFLTKの各種ヘッダファイルをグループ化したものです。FLTK1.1でもFLTK1.3.8でも同じように使えるはずです。

#ifndef GRAPH_GUARD
#define GRAPH_GUARD 1

#include "Point.h"
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <iostream>
#include <stdio.h>
#include <vector>
#include <cmath> // コメントアウトになっていた

using std::string; using std::initializer_list;
using std::vector; using std::cout;

// このエラー関数が存在していなかった
void error (const char* message) ;

namespace Graph_lib {
#undef major
#undef minor

struct Color {
	enum Color_type {
		red=FL_RED, blue=FL_BLUE, green=FL_GREEN,
		yellow=FL_YELLOW, white=FL_WHITE, black=FL_BLACK,
		magenta=FL_MAGENTA, cyan=FL_CYAN, dark_red=FL_DARK_RED,
		dark_green=FL_DARK_GREEN, dark_yellow=FL_DARK_YELLOW, dark_blue=FL_DARK_BLUE,
		dark_magenta=FL_DARK_MAGENTA, dark_cyan=FL_DARK_CYAN
	};
	enum Transparency { invisible = 0, visible=255 };

	Color(Color_type cc) :c(Fl_Color(cc)), v(visible) { }
	Color(Color_type cc, Transparency vv) :c(Fl_Color(cc)), v(vv) { }
	Color(int cc) :c(Fl_Color(cc)), v(visible) { }
	Color(Transparency vv) :c(Fl_Color()), v(vv) { }

	int as_int() const { return c; }
	char visibility() const { return v; }
	void set_visibility(Transparency vv) { v=vv; }
private:
	unsigned char v;
	Fl_Color c;
};

Graph.h, Graph.cpp 全ソースコード

[C++] 名著”プログラミング入門”のGUIを作成

[M1 Mac, Big Sur 11.6.7, FLTK 1.3.8, clang 13.0.0, no IDE]

ストラウストラップ氏の名著”プログラミング入門”(原書初版2008年)のGUIソースコード(日本語版P362)が現在の環境では動かないため関連ファイルを修正しました。

ヘッダファイル等はストラウストラップ氏のホームページから入手できます。こちらの方に手を入れました。

50個ほどのエラーを直していく気の遠くなるような作業でしたが、何とか復元できました。S氏はFLTKのインストールと設定は経験者でも難しいと説明しています。確かに普段使いしている私もライブラリの選択などで手間取りましたから、かなりの方が苦労していると思います。

ソースコードは次回以降アップします。