From 3e3d8d6c13e6b4207a97aee117236b8ca70b9fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Fri, 26 Aug 2022 09:10:38 +0200 Subject: Use CMake. I don't love it, but it makes it possible to support Visual Studio in addition to MinGW GCC. --- .dir-locals.el | 3 +-- Makefile | 76 +++++++++++++++++--------------------------------------- c/CMakeLists.txt | 47 +++++++++++++++++++++++++++++++++++ eb.el | 15 ++++++++++- makedeps | 58 ------------------------------------------ showdeps | 28 --------------------- showtodo | 27 -------------------- 7 files changed, 85 insertions(+), 169 deletions(-) create mode 100644 c/CMakeLists.txt delete mode 100644 makedeps delete mode 100644 showdeps delete mode 100644 showtodo diff --git a/.dir-locals.el b/.dir-locals.el index 65d846b..e3f9e92 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -1,5 +1,4 @@ -((nil . ((compile-command . "make -j -O -k "))) - (c-mode . ((mode . c++))) +((c-mode . ((mode . c++))) (c++-mode . ((flycheck-gcc-include-path . ("C:/Program Files/swipl/include" "C:/msys64/mingw64/include/libxml2")) (flycheck-gcc-definitions . ("UNICODE" "_UNICODE")) diff --git a/Makefile b/Makefile index 50f5e00..f6d8bee 100644 --- a/Makefile +++ b/Makefile @@ -1,61 +1,31 @@ -EXE = EpisodeBrowser.exe +SYSTEM ?= vs2019 -OBJ = b/datalistview.obj -OBJ += b/data.obj -OBJ += b/debug.obj -OBJ += b/episodelistview.obj -OBJ += b/ext.obj -OBJ += b/layout.obj -OBJ += b/listview.obj -OBJ += b/main.obj -OBJ += b/resource.obj -OBJ += b/test.obj -OBJ += b/win.obj +EXE = b/$(SYSTEM)/EpisodeBrowser.exe +ifneq ($(SYSTEM), mingw) +EXE = b/$(SYSTEM)/Debug/EpisodeBrowser.exe +endif -CC = gcc -CFLAGS = -DUNICODE -D_UNICODE -CFLAGS += -D_DEBUG -CFLAGS += -std=c++17 -mwindows -O0 -CFLAGS += -IC:/msys64/mingw64/include/libxml2 -CFLAGS += -Wall -Wextra -Wpedantic -Wno-missing-field-initializers -Wno-parentheses -LDFLAGS += -lstdc++ -lcomctl32 -lwininet -llibxml2 - -all: showdeps b/$(EXE) - cp b/$(EXE) "C:\Users\John\Desktop\Delat" +all: + cd b/$(SYSTEM) && cmake --build . -j +ifneq ($(SYSTEM), mingw) + cp x/l/libxml2.dll b/$(SYSTEM)/Debug +endif + cp $(EXE) "C:\Users\John\Desktop\Delat" clean: - rm -fr b/$(EXE) b/*.obj + cd b/$(SYSTEM) && cmake --build . --target clean TAGS: c/*.cpp c/*.h etags --declarations -lc++ c/*.cpp c/*.h -b/$(EXE): Makefile $(OBJ) - $(CC) $(CFLAGS) -o $@ $(OBJ) $(LDFLAGS) - -b/resource.obj: c/resource.h c/resource.rc c/application.manifest - windres -i c/resource.rc -o b/resource.obj - -b/%.obj: c/%.cpp - $(CC) -c $(CFLAGS) -o $@ $< - -s/%.s: c/%.cpp - $(CC) $(CFLAGS) -fverbose-asm -masm=intel -S -o $@ $< - -# showdeps prints a short summary of which dependencies have changed, -# causing which targets to be rebuilt. It is run by the `all' target -# by default. -.PHONY: showdeps -showdeps: - @perl showdeps - -# showdeps prints all TODO comments in the C++ source files. -.PHONY: showtodo -showtodo: - @perl showtodo - -# deps.mk includes additional, dynamically generated dependencies for -# b/*.obj and b/EpisodeBrowser.exe. Because it is included below, GNU -# make should build deps.mk automatically. -deps.mk: c/*.cpp - @perl makedeps --include deps.mk +.PHONY: mingw vs2019 +b: + mkdir b +b/mingw: b + mkdir b/mingw +b/vs2019: b + mkdir b/vs2019 +mingw: b/mingw + cd b/mingw && cmake -G "Unix Makefiles" ../../c +vs2019: b/vs2019 + cd b/vs2019 && cmake -G "Visual Studio 16 2019" ../../c diff --git a/c/CMakeLists.txt b/c/CMakeLists.txt new file mode 100644 index 0000000..1bfcac3 --- /dev/null +++ b/c/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.10) +project(EpisodeBrowser) + +set(MSVC_EXT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../x/h) +set(MSVC_EXT_LINK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../x/l) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) +add_compile_definitions(UNICODE _UNICODE) + +add_executable(EpisodeBrowser WIN32) +target_sources(EpisodeBrowser PRIVATE + data.cpp + data.h + datalistview.cpp + datalistview.h + debug.cpp + debug.h + episodelistview.cpp + episodelistview.h + ext.cpp + ext.h + layout.cpp + layout.h + listview.cpp + listview.h + main.cpp + resource.h + resource.rc + test.cpp + test.h + util.h + win.cpp + win.h) + +if (CMAKE_GENERATOR MATCHES "Visual Studio") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /MANIFEST:NO") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO") + target_compile_options(EpisodeBrowser PRIVATE /wd26451 /wd6385) + target_include_directories(EpisodeBrowser PUBLIC ${MSVC_EXT_INCLUDE_DIR}) + find_library(LIBXML2 libxml2 HINTS ${MSVC_EXT_LINK_DIR}) + target_link_libraries(EpisodeBrowser comctl32 wininet ${LIBXML2}) +else() + target_include_directories(EpisodeBrowser PUBLIC C:/msys64/mingw64/include/libxml2) + target_link_libraries(EpisodeBrowser stdc++ comctl32 wininet libxml2) +endif() diff --git a/eb.el b/eb.el index 594c4e3..52c67f6 100644 --- a/eb.el +++ b/eb.el @@ -4,11 +4,21 @@ ;;; Code: +(defcustom eb-system "vs2019" + "Build system (mingw/vs2019)." + :group 'eb + :type 'string) + (defcustom eb-cwd "b" "Working directory for executable." :group 'eb :type 'directory) +(defcustom eb-cppclean-argv (list "cppclean") + "Argument vector for cppclean." + :group 'eb + :type 'sexp) + ;;;###autoload (defun eb-run () "Launch built executable, displaying its output in a buffer." @@ -16,7 +26,10 @@ (require 'project) (let ((buf (get-buffer-create "*eb-run*")) (exe (concat (project-root (project-current)) - "/b/EpisodeBrowser.exe")) + "/b/" + eb-system + (if (not (string-equal eb-system "mingw")) "/Debug/" "") + "EpisodeBrowser.exe")) (default-directory eb-cwd)) (with-current-buffer buf (compilation-mode)) diff --git a/makedeps b/makedeps deleted file mode 100644 index 70589ca..0000000 --- a/makedeps +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env perl - -use v5.12; -use warnings; -use subs qw/for_includes/; - -open my $fh, ">", "deps.mk"; -print $fh "# This file is generated by makedeps.\n"; - -while (my $f = glob("c/*.cpp")) { - $f =~ s,^c/,,; - $f =~ s/\.cpp$//; - - if ($f eq "main") { print $fh "b/\$(EXE):"; } - else { print $fh "b/$f.obj:"; } - - # Print dependencies in source file. - my @deps; - for_includes "c/$f.cpp", sub { - my $f = shift; - return if grep { $_ eq $f } @deps; - push @deps, $f; - print $fh " c/$f"; - - # Print dependencies in dependency. - for_includes "c/$f", sub { - my $f = shift; - return if grep { $_ eq $f } @deps; - push @deps, $f; - print $fh " c/$f"; - } - }; - - print $fh "\n"; -} - -sub for_includes ($&) { - my $f = shift; - my $c = shift; - state %cache; - - # Retrieve dependencies from cache. - if (exists $cache{$f}) { - $c->($_) for @{$cache{$f}}; - } - - # Find dependencies in file. - else { - open my $gh, "<", $f or die "($f) $!"; - while ($_ = <$gh>) { - next if /^$/; - last if not /#/; - next if not /^#include\s*"([^"]+)"/; - push @{$cache{$f}}, $1; - $c->($1); - } - } -} diff --git a/showdeps b/showdeps deleted file mode 100644 index 56d355f..0000000 --- a/showdeps +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env perl - -use strict; -use warnings; - -my @targets; -my @keys; -my %prereqs; - -$ENV{LANGUAGE} = "en_US"; -for (`make --debug=b -n`) { - next if not /Prerequisite [`']([^']+)' is newer than target [`']([^']+)'/; - - # Don't consider prerequisites that are targets. - unless ($ARGV[0] and $ARGV[0] eq '-a') { - push @targets, $2 if not grep { $_ eq $2 } @targets; - next if grep { $_ eq $1 } @targets; - } - - push @keys, $1 if not grep { $_ eq $1 } @keys; - push @{$prereqs{$1}}, $2 if not grep { $_ eq $2 } @{$prereqs{$1}}; -} - -if (@keys) { - print "---\n"; - print "$_ -> @{$prereqs{$_}}\n" for @keys; - print "---\n"; -} diff --git a/showtodo b/showtodo deleted file mode 100644 index 475e492..0000000 --- a/showtodo +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env perl - -use strict; -use warnings; - -# Note that this script only supports /* C-style */ comments. - -while (my $f = glob("c/*.*")) { - open my $fh, "<", $f; - my $line; - while (<$fh>) { - $line++; - next if not m{TODO:}; # Skip fast. - - next if not m{^\s*/?\*.*\s(TODO:.*)\s*(\*/)?}; - print "$f:$line: $1\n"; - next if $2; - - # Continue text if comment is not finished. - my $pad = " " x length("$f:$line: "); - while (<$fh>) { - (my $text = $_) =~ s{^\s*\*?\s*|\s*\*/}{}g; - print "$pad$text"; - last if m{\*/}; - } - } -} -- cgit v1.2.3