Thread: Capturing keyboard scancodes....

  1. #16
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96

    Makefile problems.

    Quote Originally Posted by migf1 View Post
    I just re-read my last post and I realized that you may conclude that you cannot connect both a key-press and a mouse-button press signal handler to your window (or any widget for that matter). You can connect as many signal handlers as you want to any widget.

    Also, I'm using the macro MYGTK2_DBG_STDERR_MSG() but haven't given code for it:

    Code:
    /**
     * Macro displaying an error-message with debugging info in the stderr stream.
     */
    #define MYGTK2_DBG_STDERR_MSG( errmsg )                         \
    do {                                                            \
        if ( !global_mygtk2debug )                              \
            break;                                          \
        fputs( "*** ERROR:\n", stderr );                        \
        fprintf(stderr,                                         \
            "*** File : %s | Func: %s | Line: %d\n*** %s\n",\
            __FILE__, __func__,  __LINE__,                  \
            (const char *)(errmsg) ? errmsg : "\0"          \
            );                                              \
    } while(0)
    PS. Another inconsistency on my part. For keys I use MYGTK2_DBG_ERRMSG(), while for mouse-buttons I use MYGTK2_DBG_STDERR_MSG() ... I should fix that too (someday )
    Thanks Migf1. I'll keep that in mind. Right now, I'm having some difficulties with my Makefile. Here's what I have so far with it:
    Code:
    # Our Makefile
    
    
    # Set our C flags
    CFLAGS := -Wall -mms-bitfields
    
    
    # Define directories that contain header files other than the default search dir
    INCLUDES := -I./include
    
    
    # Define library directories that aren't in the default searhc dir
    LDFLAGS := -L./lib
    
    
    # Define a directory to store object files in so we don't clutter up the place
    OBJDIR = ./obj
    
    
    # Define a directory to hold our src files
    SRCDIR = ./src
    
    
    # Default directory for where the executables get stored.
    BINDIR = ./bin
    
    
    # For a default architecture, we pick Linux
    ARCH = Linux
    
    
    # Define any libraries we need to link into the executable
    LIBS := -lncurses
    
    
    # Define the default executable file name
    # (in Linux, this will default to linux_x64)
    PROJECT = main
    
    
    # Define the C source files
    SOURCES = gtk3.c main.c status.c
    
    
    # A simple way of adding $(OBJDIR) directory to each file
    # and replacing the .c at the end of our sources with a .o
    OBJECTS = $(addprefix $(OBJDIR)/, $(SOURCES:.c=.o) )
    
    
    # A default extension for our objects
    OBJ_EXT = _x64.o
    
    
    default: linux_cc clean $(SOURCES) $(PROJECT)
    
    
    linux: linux_cc clean $(SOURCES) $(PROJECT)
    
    
    win32: win32_cc clean $(SOURCES) $(PROJECT)
    
    
    win64: win64_cc clean $(SOURCES) $(PROJECT)
    
    
    $(PROJECT): $(OBJECTS)
        @echo -e "\e[34;1mLinking object files for $(PROJECT)...\e[0m"
        $(CC) $(OBJECTS) -o $(BINDIR)/$(ARCH)/$(PROJECT) $(LDFLAGS) $(LIBS)
        @echo -e "\n"
        @echo -e "\e[32;1m$(BINDIR)/$(ARCH)/$(PROJECT)\e[34;1m was successfully created...\e[0m"
    
    
    # With the eval line, we replace the filename.o with filename_arch.o
    $(OBJDIR)/%.o : %.c
        @echo -e "\e[34;1mCompiling object files for $(PROJECT)...\e[0m"
        $(eval OBJECT = ./$(@:.o=$(OBJ_EXT).o))
        $(CC) $(CFLAGS) $(INCLUDES) -c $(SRCDIR)/$< -o $(OBJECT)
        @echo -e "\n"
    
    
    # Just in case we end up ever using file names like all, clean, linux, etc
    # we declare them as phony so they don't actually get built.
    .PHONY: all clean linux win32_cc win64_cc
    
    
    # We only want cleaned what's being built.  For example, if we already have 
    # main_x86.exe, main_x86.o built, we don't want make win64 to clean it out.
    # We only want make win64 to clean main_x64.exe and main_x64.o.
    clean:
        @echo -e "\e[34;1mCleaning up a little bit (run make clean_all to clean up everything)...\e[0m"
        @echo -e "\e[31;1mrm -f $(OBJDIR)/*.o \e[0m\n"
        @-rm -f $(OBJDIR)/*.o
    
    
    clean_all:
        @echo -e "\e[34;1mCleaning up everything...\e[0m"
        @echo -e "\e[31;1mrm -rf $(OBJDIR) $(BINDIR) \e[0m\n"
        @-rm -fr $(OBJDIR) $(BINDIR)
    
    
    # CC is the compiler that we use.
    # PROJECT is the name of the executable that we'll be creating.
    # OBJECTS are the object files.  We store them as object_arch.o
    # instead of just object.o because we're compiling for multiple
    # architects at the same time.
    
    
    # Settings specific to our Linux build.
    linux_cc:
        $(eval ARCH = Linux)
        @if [ ! -d "$(BINDIR)/$(ARCH)" ]; then \
            echo -e "\e[34;1mCreating executable output directory: \e[36;1m$(BINDIR)/$(ARCH)\n\e[0m"; \
            mkdir -p $(BINDIR)/$(ARCH); \
        fi
    
    
        @if [ ! -d "$(OBJDIR)" ]; then \
            echo -e "\e[34;1mCreating an obj directory: $(OBJDIR)\n\e[0m"; \
            mkdir -p $(OBJDIR); \
        fi
    
    
        $(eval CC = gcc)
        $(eval CFLAGS := $(CFLAGS) -pthread)
        $(eval PROJECT = linux_x64)
        $(eval OBJ_EXT = _lin.o)
        $(eval OBJECTS = $(addprefix $(OBJDIR)/, $(SOURCES:.c=$(OBJ_EXT))))
    
    
        $(eval INCLUDES := $(INCLUDES)    -I"/usr/include/gtk-3.0" \
                        -I"/usr/include/at-spi2-atk/2.0" \
                        -I"/usr/include/at-spi-2.0" \
                        -I"/usr/include/dbus-1.0" \
                        -I"/usr/lib64/dbus-1.0/include" \
                        -I"/usr/include/gtk-3.0" \
                        -I"/usr/include/gio-unix-2.0/" \
                        -I"/usr/include/pkg/wayland" \
                        -I"/usr/include/pkg/libxkbcommon" \
                        -I"/usr/include/pkg/wayland" \
                        -I"/usr/include/cairo" \
                        -I"/usr/include/pango-1.0" \
                        -I"/usr/include/harfbuzz" \
                        -I"/usr/include/pango-1.0" \
                        -I"/usr/include/atk-1.0" \
                        -I"/usr/include/cairo" \
                        -I"/usr/include/pixman-1" \
                        -I"/usr/include/freetype2" \
                        -I"/usr/include/libdrm" \
                        -I"/usr/include/libpng16" \
                        -I"/usr/include/gdk-pixbuf-2.0" \
                        -I"/usr/include/libpng16" \
                        -I"/usr/include/glib-2.0" \
                        -I"/usr/lib64/glib-2.0/include")
    
    
        $(eval LIBS := $(LIBS)        -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 \
                        -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 \
                        -lgio-2.0 -lgobject-2.0 -lglib-2.0)
    
    
    # Settings specific to our win32 build
    win32_cc:
        $(eval ARCH = win32)
        @if [ ! -d "$(BINDIR)/$(ARCH)" ]; then \
            echo -e "\e[34;1mCreating executable output directory: \e[36;1m$(BINDIR)/$(ARCH)\e[0m"; \
            mkdir -p $(BINDIR)/$(ARCH); \
        fi
    
    
        @if [ ! -d "$(OBJDIR)" ]; then \
            echo -e "\e[34;1mCreating an obj directory: \e[36;1m$(OBJDIR)\n\e[0m"; \
            mkdir -p $(OBJDIR); \
        fi
    
    
        $(eval CC = i686-w64-mingw32-gcc.exe)
        $(eval OBJ_EXT = _x86)
        $(eval PROJECT = $(PROJECT)$(OBJ_EXT).exe)
        $(eval OBJECTS = $(addprefix $(OBJDIR)/, $(SOURCES:.c=$(OBJ_EXT).o)))
    
    
        $(eval INCLUDES := $(INCLUDES)    -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/gtk-3.0" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/cairo" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/pango-1.0" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/atk-1.0" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/cairo" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/pixman-1" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/freetype2" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/libpng15" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/gdk-pixbuf-2.0" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/libpng15" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/include/glib-2.0" \
                        -I"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/lib/glib-2.0/include")
    
    
        $(eval LDFLAGS := $(LDFLAGS)    -L"C:/Program Files (x86)/mingw-w64/gtk+-3.6.4_win32/lib" \
                        -L"C:/Program Files (x86)/mingw-w64/i686-5.1.0-posix-sjlj-rt_v4-rev0/mingw32/opt/lib")
    
    
        $(eval LIBS := $(LIBS)        -lgtk-3 -lgdk-3 -lgdi32 -limm32 -lshell32 -lole32 -Wl,-luuid \
                        -lpangocairo-1.0 -lpangoft2-1.0 -lfreetype \
                        -lfontconfig -lpangowin32-1.0 -lgdi32 -lpango-1.0 \
                        -lm -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 \
                        -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lintl)
    
    
    # Settings specific to our win64 build
    win64_cc:
        $(eval ARCH = win64)
        @if [ ! -d "$(BINDIR)/$(ARCH)" ]; then \
            echo -e "\e[34;1mCreating executable output directory: \e[36;1m$(BINDIR)/$(ARCH)\n\e[0m"; \
            mkdir -p $(BINDIR)/$(ARCH); \
        fi    $(eval CC = x86_64-w64-mingw32-gcc.exe)
    
    
        @if [ ! -d "$(OBJDIR)" ]; then \
            echo -e "\e[34;1mCreating an obj directory: \e[36;1m$(OBJDIR)\n\e[0m"; \
            mkdir -p $(OBJDIR); \
        fi
    
    
        $(eval OBJ_EXT = _x64)
        $(eval PROJECT = $(PROJECT)$(OBJ_EXT).exe)
        $(eval OBJECTS = $(addprefix $(OBJDIR)/, $(SOURCES:.c=$(OBJ_EXT).o)))
    
    
        $(eval INCLUDES := $(INCLUDES)    -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/gtk-3.0" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/cairo" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/pango-1.0" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/atk-1.0" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/cairo" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/pixman-1" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/freetype2" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/libpng15" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/gdk-pixbuf-2.0" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/libpng15" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/include/glib-2.0" \
                        -I"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/lib/glib-2.0/include")
    
    
        $(eval LDFLAGS := $(LDFLAGS)    -L"C:/Program Files/mingw-w64/gtk+-3.6.4_win64/lib" \
                        -L"C:/Program Files/mingw-w64/x86_64-5.1.0-posix-seh-rt_v4-rev0/mingw64/opt/lib")
    
    
        $(eval LIBS := $(LIBS)        -lgtk-3 -lgdk-3 -lgdi32 -limm32 -lshell32 -lole32 -Wl,-luuid \
                        -lpangocairo-1.0 -lpangoft2-1.0 -lfreetype \
                        -lfontconfig -lpangowin32-1.0 -lgdi32 -lpango-1.0 \
                        -lm -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 \
                        -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lintl)

  2. #17
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    Here's some of the things I've tried. One, I tried changing this line:
    Code:
    win32: win32_cc clean $(SOURCES) $(PROJECT)
    

    to this line:
    Code:
    
    
    Code:
    win32: win32_cc clean $(SRCDIR)/$(SOURCES) $(PROJECT)
    

    That gives me an error message,
    Code:
    Cleaning up a little bit (run make clean_all to clean up everything)...
    rm -f ./obj/*.o
    
    
    make: *** No rule to make target `main.c', needed by `win32'.  Stop.
    So I try changing this line:
    Code:
    $(OBJDIR)/%.o : %.c
    to this code
    Code:
    $(OBJDIR)/%.o : $(SRCDIR)/%.c
    However, that gives me the exact same error message. Can anyone tell me how to fix this so it works the way I'd like it to work?

  3. #18
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    I was able to use VPATH to get it to do what I want. Now I have one more problem. I want something like this:
    win: win32 win64
    where when I call make win, make will make the win32 and then the win64 rules. I'd also like to be able to switch default from linux to win and from win to linux easy like. However, when I try writing a rule like: win: win32 win64 make win only executes the win32 stuff, not the win64 stuff.

  4. #19
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    May I suggest you start with a minimal Makefile, and only add decorations and options after you get it working?

    Let's start with a simple GTK+ 2 example program, split into two files just to make sure our Makefile will work right. I'm not suggesting you split your applications this way; I do not, this is just to test the Makefile logic. (I prefer to put GTK+ stuff in my main C file, and put non-GTK processing in separate files, if I can test them separately. Otherwise in the same file all they go.)

    src/example.c:
    Code:
    #include <stdlib.h>
    #include <gtk/gtk.h>
    #include "mystuff.h"
    
    int main(int argc, char *argv[])
    {
        GtkWidget *window;
    
        gtk_init(&argc, &argv);
    
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
        gtk_window_set_title(GTK_WINDOW(window), "Example");
        gtk_window_set_role(GTK_WINDOW(window), "example-gtk-program");
        gtk_window_set_decorated(GTK_WINDOW(window), TRUE);
    
        mystuff(window);
    
        gtk_widget_show(window);
        gtk_main();
    
        return EXIT_SUCCESS;
    }
    src/mystuff.h:
    Code:
    #ifndef   MYSTUFF_H
    #define   MYSTUFF_H
    #include <gtk/gtk.h>
    
    void mystuff(GtkWidget *window);
    
    #endif /* MYSTUFF_H */
    src/mystuff.c:
    Code:
    #include <gtk/gtk.h>
    
    void mystuff(GtkWidget *window)
    {
        GtkWidget *view;
    
        view = gtk_text_view_new();
        gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)), "Hello, world!", -1);
    
        gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(view), FALSE);
        gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE);
    
        gtk_container_add(GTK_CONTAINER(window), view);
    
        gtk_widget_show(view);
    }
    Typically, the following Makefile should work on any architecture and OS:
    Code:
    GTKVER       := 2.0
    PKGCONFIG    := pkg-config
    CC           := gcc
    CFLAGS       := $(shell $(PKGCONFIG) --cflags gtk+-$(GTKVER))
    LD           := $(CC)
    LDFLAGS      := $(shell $(PKGCONFIG) --libs gtk+-$(GTKVER))
    
    EXAMPLE_BIN  := example
    EXAMPLE_OBJS := example.o mystuff.o
    PROGS        := $(EXAMPLE_BIN)
    
    OBJDIR       := build
    SRCDIR       := src
    
    .PHONY: all clean
    
    all: $(addprefix $(OBJDIR)/, $(PROGS))
    
    clean:
    	rm -rf $(OBJDIR)
    
    $(OBJDIR):
    	mkdir $(OBJDIR)
    
    $(OBJDIR)/%.o: $(SRCDIR)/%.c $(OBJDIR)
    	$(CC) $(CFLAGS) -c $< -o $@
    
    $(OBJDIR)/$(EXAMPLE_BIN): $(addprefix $(OBJDIR)/, $(EXAMPLE_OBJS))
    	$(LD) $^ $(LDFLAGS) -o $@
    However, if you have OS/architecture specific files you may need to compile in, I guess something like the following Makefile might work:
    Code:
    GTKVER := 2.0
    OBJDIR := build
    SRCDIR := src
    
    EXAMPLE_OBJS := example.o mystuff.o
    
    #
    # Automagic architecture detection.
    #
    ifeq ($(ARCH),)
    ifeq ($(OS),Windows_NT)
    ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
    ARCH := win64
    endif
    ifeq ($(PROCESSOR_ARCHITECTURE),x64)
    ARCH := win32
    endif
    endif
    ifeq ($(shell uname -s),Linux)
    ARCH := linux
    endif
    endif
    
    #
    # Defaults for ARCH=linux
    #
    ifeq ($(ARCH),linux)
    CC           := gcc
    CFLAGS       := $(shell pkg-config --cflags gtk+-$(GTKVER))
    LD           := $(CC)
    LDFLAGS      := $(shell pkg-config --libs gtk+-$(GTKVER))
    EXAMPLE_BIN  := example
    endif
    
    #
    # Defaults for ARCH=win64
    #
    ifeq ($(ARCH),win64)
    CC           := x86_64-w64-mingw32-gcc.exe
    MINGWDIR     := "C:/Program Files/mingw-w64"
    GTKDIR       := "$(MINGWDIR)/gtk+-3.6.4_win64"
    CFLAGS       := "-I$(GTKDIR)/include/gtk-3.0" \
                    "-I$(GTKDIR)/include/cairo" \
                    "-I$(GTKDIR)/include/pango-1.0" \
                    "-I$(GTKDIR)/include/atk-1.0" \
                    "-I$(GTKDIR)/include/cairo" \
                    "-I$(GTKDIR)/include/pixman-1" \
                    "-I$(GTKDIR)/include" \
                    "-I$(GTKDIR)/include/freetype2" \
                    "-I$(GTKDIR)/include" \
                    "-I$(GTKDIR)/include/libpng15" \
                    "-I$(GTKDIR)/include/gdk-pixbuf-2.0" \
                    "-I$(GTKDIR)/include/libpng15" \
                    "-I$(GTKDIR)/include/glib-2.0" \
                    "-I$(GTKDIR)/lib/glib-2.0/include"
    LD           := $(CC)
    LDFLAGS      := "-L$(MINGWDIR)/lib" \
                    "-L$(MINGWDIR)/x86_64-5.1.0-posix-seh-rt_v4-rev0/mingw64/opt/lib"
    EXAMPLE_BIN  := example.exe
    endif
    
    ifeq ($(ARCH),)
    $(error ARCH unset.)
    endif
    
    #
    # Recipes
    #
    
    .PHONY: all clean
    
    all: $(OBJDIR)/$(EXAMPLE_BIN)
    
    clean:
    	rm -rf $(OBJDIR)
    
    $(OBJDIR):
    	mkdir $(OBJDIR)
    
    $(OBJDIR)/%.o: $(SRCDIR)/%.c $(OBJDIR)
    	$(CC) $(CFLAGS) -c $< -o $@
    
    $(OBJDIR)/$(EXAMPLE_BIN): $(addprefix $(OBJDIR)/, $(EXAMPLE_OBJS))
    	$(LD) $^ $(LDFLAGS) -o $@
    but I definitely do not recommend the latter approach, unless the first one cannot be made to work.

    In both cases the default target compiles the binary (although I personally prefer to use make clean all ). To override the architecture, use make ARCH=linux clean all for example.

  5. #20
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    Quote Originally Posted by Nominal Animal View Post
    May I suggest you start with a minimal Makefile, and only add decorations and options after you get it working?
    I did just that. I created a very basic makefile that compiled just one C file, main.c. Over time (about a week), I've adapted it accordingly. Makefiles are not my strong suit but I tried my best.

    Quote Originally Posted by Nominal Animal View Post
    Let's start with a simple GTK+ 2 example program, split into two files just to make sure our Makefile will work right. I'm not suggesting you split your applications this way; I do not, this is just to test the Makefile logic. (I prefer to put GTK+ stuff in my main C file, and put non-GTK processing in separate files, if I can test them separately. Otherwise in the same file all they go.)
    ...
    Typically, the following Makefile should work on any architecture and OS:
    Code:
    GTKVER       := 2.0
    PKGCONFIG    := pkg-config
    CC           := gcc
    CFLAGS       := $(shell $(PKGCONFIG) --cflags gtk+-$(GTKVER))
    LD           := $(CC)
    LDFLAGS      := $(shell $(PKGCONFIG) --libs gtk+-$(GTKVER))
    
    EXAMPLE_BIN  := example
    EXAMPLE_OBJS := example.o mystuff.o
    PROGS        := $(EXAMPLE_BIN)
    
    OBJDIR       := build
    SRCDIR       := src
    
    .PHONY: all clean
    
    all: $(addprefix $(OBJDIR)/, $(PROGS))
    
    clean:
        rm -rf $(OBJDIR)
    
    $(OBJDIR):
        mkdir $(OBJDIR)
    
    $(OBJDIR)/%.o: $(SRCDIR)/%.c $(OBJDIR)
        $(CC) $(CFLAGS) -c $< -o $@
    
    $(OBJDIR)/$(EXAMPLE_BIN): $(addprefix $(OBJDIR)/, $(EXAMPLE_OBJS))
        $(LD) $^ $(LDFLAGS) -o $@
    This is the approach I wanted to use the most. However, because in Windows, I need the 32-bit and the 64-bit version of GTK+, I cannot have the GTK+ bin folder in the path. I could, but the Makefile, when it calls pkg-config, would only call the pkg-config who's bin file path was listed first in the %PATH% environment. I could not find an easy way, without hard coding the path to pkg-config in the Makefile, to make it work. You know, a variable that holds the path to a specific win32 pkg-config bin executable, a variable that holds the path to a specific win64 pkg-config bin executable, etc. I didn't think this would be the best way. I guess it'd be better than hard coding the GTK+ include files for the Windows builds.

    Quote Originally Posted by Nominal Animal View Post
    However, if you have OS/architecture specific files you may need to compile in, I guess something like the following Makefile might work:
    Code:
    GTKVER := 2.0
    OBJDIR := build
    SRCDIR := src
    
    EXAMPLE_OBJS := example.o mystuff.o
    
    #
    # Automagic architecture detection.
    #
    ifeq ($(ARCH),)
    ifeq ($(OS),Windows_NT)
    ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
    ARCH := win64
    endif
    ifeq ($(PROCESSOR_ARCHITECTURE),x64)
    ARCH := win32
    endif
    endif
    ifeq ($(shell uname -s),Linux)
    ARCH := linux
    endif
    endif
    
    #
    # Defaults for ARCH=linux
    #
    ifeq ($(ARCH),linux)
    CC           := gcc
    CFLAGS       := $(shell pkg-config --cflags gtk+-$(GTKVER))
    LD           := $(CC)
    LDFLAGS      := $(shell pkg-config --libs gtk+-$(GTKVER))
    EXAMPLE_BIN  := example
    endif
    
    #
    # Defaults for ARCH=win64
    #
    ifeq ($(ARCH),win64)
    CC           := x86_64-w64-mingw32-gcc.exe
    MINGWDIR     := "C:/Program Files/mingw-w64"
    GTKDIR       := "$(MINGWDIR)/gtk+-3.6.4_win64"
    CFLAGS       := "-I$(GTKDIR)/include/gtk-3.0" \
                    "-I$(GTKDIR)/include/cairo" \
                    "-I$(GTKDIR)/include/pango-1.0" \
                    "-I$(GTKDIR)/include/atk-1.0" \
                    "-I$(GTKDIR)/include/cairo" \
                    "-I$(GTKDIR)/include/pixman-1" \
                    "-I$(GTKDIR)/include" \
                    "-I$(GTKDIR)/include/freetype2" \
                    "-I$(GTKDIR)/include" \
                    "-I$(GTKDIR)/include/libpng15" \
                    "-I$(GTKDIR)/include/gdk-pixbuf-2.0" \
                    "-I$(GTKDIR)/include/libpng15" \
                    "-I$(GTKDIR)/include/glib-2.0" \
                    "-I$(GTKDIR)/lib/glib-2.0/include"
    LD           := $(CC)
    LDFLAGS      := "-L$(MINGWDIR)/lib" \
                    "-L$(MINGWDIR)/x86_64-5.1.0-posix-seh-rt_v4-rev0/mingw64/opt/lib"
    EXAMPLE_BIN  := example.exe
    endif
    
    ifeq ($(ARCH),)
    $(error ARCH unset.)
    endif
    
    #
    # Recipes
    #
    
    .PHONY: all clean
    
    all: $(OBJDIR)/$(EXAMPLE_BIN)
    
    clean:
        rm -rf $(OBJDIR)
    
    $(OBJDIR):
        mkdir $(OBJDIR)
    
    $(OBJDIR)/%.o: $(SRCDIR)/%.c $(OBJDIR)
        $(CC) $(CFLAGS) -c $< -o $@
    
    $(OBJDIR)/$(EXAMPLE_BIN): $(addprefix $(OBJDIR)/, $(EXAMPLE_OBJS))
        $(LD) $^ $(LDFLAGS) -o $@
    but I definitely do not recommend the latter approach, unless the first one cannot be made to work.

    In both cases the default target compiles the binary (although I personally prefer to use make clean all ). To override the architecture, use make ARCH=linux clean all for example.
    Why would you not recommend the second approach? I guess the problem isn't necessarily detecting the architecture. That was the reason I was having the win32 and win64 targets. In Windows 64-bit, I could compile win32 executables by typing make win32. In the second example, I'd have to override, right? make ARCH=win32 ? Also, shouldn't:
    Code:
    ifeq ($(PROCESSOR_ARCHITECTURE),x64)
    ARCH := win32
    endif
    actually be:
    Code:
    ifeq ($(PROCESSOR_ARCHITECTURE),x86)
    ARCH := win32
    endif
    Notice how I replaced x64 with x86. I appreciate the help.

    If I could get the first Makefile to work with my system, that'd be the best.

    When I build the 64-bit version, I need the pkg-config that is located in: "\Program Files\mingw-w64\gtk+-3.6.4_win64\bin\pkg-config.exe
    When I build the 32-bit version, I need the pkg-config that is located in: "\Program Files (x86)\mingw-w64\gtk+-3.6.4_win32\bin\pkg-config.exe"

  6. #21
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    Also, you're saying I should keep my .h header files in the src directory with my .c files? I also have a library I have to compile. It'll be located in the lib directory. That shouldn't be too hard to do. I could compile it a head of time and then just have my C program call the functions from it and install it when it's done. In Windows, I'm guessing it's going to be compiled as DLL. Linux, probably a .a or something. I mean the other option would be to build the library with the src code each time.
    Last edited by Spork Schivago; 08-24-2015 at 12:03 PM.

  7. #22
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    Man, I'm so close. I changed the GTKVER to 3.0, because I'm using GTK 3. I changed the src files in the first Makefile to match mine. I add the 32-bit gtk3 bin path to my path variable, because gcc --version shows the 32-bit version of GCC is being called...this is what I get when I type make

    Code:
    gcc -mms-bitfields -Ic:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include
    /gtk-3.0 -Ic:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/cairo -Ic
    :/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/pango-1.0 -Ic:/Progra
    m\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/atk-1.0 -Ic:/Program\ Files\
    (x86)/mingw-w64/gtk+-3.6.4_win32/include/cairo -Ic:/Program\ Files\ (x86)/mingw-
    w64/gtk+-3.6.4_win32/include/pixman-1 -Ic:/Program\ Files\ (x86)/mingw-w64/gtk+-
    3.6.4_win32/include -Ic:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/includ
    e/freetype2 -Ic:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include -Ic:/P
    rogram\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/libpng15 -Ic:/Program\ F
    iles\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/gdk-pixbuf-2.0 -Ic:/Program\ File
    s\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/libpng15 -Ic:/Program\ Files\ (x86)/
    mingw-w64/gtk+-3.6.4_win32/include/glib-2.0 -Ic:/Program\ Files\ (x86)/mingw-w64
    /gtk+-3.6.4_win32/lib/glib-2.0/include  -c src/status.c -o build/status.o
    /bin/sh: -c: line 0: syntax error near unexpected token `('
    This is from the ('s and )'s in the Program Files (x86) I believe. If I manually type it but with double quotes after the -I, it compiles. Like this:
    Code:
    gcc -mms-bitfields -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/gtk-3.0" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/cairo" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/pango-1.0" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/atk-1.0" -I"c:/Program\ Files\(x86)/mingw-w64/gtk+-3.6.4_win32/include/cairo" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/pixman-1" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/freetype2" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/libpng15" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/gdk-pixbuf-2.0" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/libpng15" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/include/glib-2.0" -I"c:/Program\ Files\ (x86)/mingw-w64/gtk+-3.6.4_win32/lib/glib-2.0/include" -c src/main.c -o build/main.o
    Is there away to have pkg-config add these double quotes for each -I's? I'm using MSYS because I don't really care for Cygwin, I'm just compiling from the DOS prompt, I need to treat ('s and )'s special. Escaping them doesn't work either. The only way I found was double quotes. If I go into MSYS's shell, by executing sh.exe, then I can use a / before the ( and one again before the ). That seems to work in the shell.
    Last edited by Spork Schivago; 08-24-2015 at 01:28 PM.

  8. #23
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    I think I'm going to need to move gtk+-3.6.4's directory, the 32-bit and the 64-bit, to something like C:\gtk+-3.6.4_win32 and C:\gtk+-3.6.4_win64. Then I can use the first Makefile, but modify it a little, to default to autodetecting the architecture and compiling for that or letting people override it, using the ARCH= as one of the make parameters.

  9. #24
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by Spork Schivago View Post
    I replaced x64 with x86.
    Good catch! (Not having Windows, I couldn't test it, obviously. It's easy to miss typos like that unless you really check via testing.)

    Quote Originally Posted by Spork Schivago View Post
    I could, but the Makefile, when it calls pkg-config, would only call the pkg-config who's bin file path was listed first in the %PATH% environment.
    Okay, so let's use the ARCH approach, and autodetection:
    Code:
    GTKVER     := 3.0
    GTKFULLVER := 3.6.4
    MINGWDIR   := "C:/Program Files (x86)/mingw-w64/"
    SRCDIR     := src
    BUILDDIR   := build
    
    #
    # Automagic architecture detection. Override using ARCH=
    #
    ifeq ($(ARCH),)
    ifeq ($(OS),Windows_NT)
    ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
    ARCH := win64
    endif
    ifeq ($(PROCESSOR_ARCHITECTURE),x86)
    ARCH := win32
    endif
    endif
    ifeq ($(shell uname -s),Linux)
    ARCH := linux
    endif
    endif
    
    #
    # Generic defaults, possibly overridden by some architectures
    #
    PKGCONFIG   := pkg-config
    EXAMPLE_BIN := example
    CC          := gcc
    LD          := $(CC)
    
    #
    # Architecture-specific overrides
    #
    ifeq ($(ARCH),win64)
    PKGCONFIG    := "$(MINGWDIR)/gtk+-$(GTKFULLVER)_win32/bin/pkg-config.exe"
    EXAMPLE_BIN  := example.exe
    endif
    ifeq ($(ARCH),win32)
    PKGCONFIG    := "$(MINGWDIR)/gtk+-$(GTKFULLVER)_win32/bin/pkg-config.exe"
    EXAMPLE_BIN  := example.exe
    endif
    
    #
    # Compiler and linker options
    #
    CFLAGS       := $(shell $(PKGCONFIG) --cflags gtk+-$(GTKVER))
    LDFLAGS      := $(shell $(PKGCONFIG) --libs gtk+-$(GTKVER))
    
    #
    # Architecture-specific compiler and linker overrides
    #
    ifeq ($(ARCH),win64)
    CFLAGS       += -m64 -march=x86-64 -mtune=generic
    LDFLAGS      += -m64 -march=x86-64 -mtune=generic
    endif
    ifeq ($(ARCH),win32)
    CFLAGS       += -m32 -march=i686 -mtune=i686
    LDFLAGS      += -m32 -march=i686 -mtune=i686
    endif
    
    #
    # Build dependencies on binaries built
    #
    EXAMPLE_OBJS := example.o mystuff.o
    
    #
    # List of programs to build
    #
    PROGS        := $(EXAMPLE_BIN)
    
    #
    # Recipes
    #
    
    .PHONY: all clean
     
    all: clean $(addprefix $(BUILDDIR)/, $(PROGS))
     
    clean:
    	rm -rf $(BUILDDIR)
     
    $(BUILDDIR):
    	mkdir $(BUILDDIR)
     
    $(BUILDDIR)/%.o: $(SRCDIR)/%.c $(BUILDDIR)
    	$(CC) $(CFLAGS) -c $< -o $@
     
    $(BUILDDIR)/$(EXAMPLE_BIN): $(addprefix $(BUILDDIR)/, $(EXAMPLE_OBJS))
    	$(LD) $^ $(LDFLAGS) -o $@
    The above lets me compile a GTK+ 2.0 Linux binary using make ARCH=linux GTKVER=2.0, a GTK+ 3.0 using make ARCH=linux GTKVER=3.0, and it should also allow the same for Windows (but I cannot test it myself). If I want to build a GTK+ 2.0 Linux binary using an older version of GCC, say GCC-4.4.7, I can run make GTKVER=2.0 CC=gcc-4.4 (as the ARCH should now be correctly autodetected).

    Remember, := assignments are immediate (evaluated at that point), but do not override command-line assignments. += adds to the existing assignment.

    Because the ARCH affects the compiler options, I added the clean target to the beginning of the default all rule. This means that the build/ subtree (which I now use the $(BUILDDIR) variable for consistency) will be removed and recreated for the default build. For a large build, I'd omit it. You see, when rebuilding for a different ARCH one must always clean first, since Make only looks at the file timestamps, and does not realize the existing versions are incompatible with the new build. So it's just a "nice to have" feature; recompiling a small program from scratch is still faster than having to type the "clean" target on the make command line.

    Quote Originally Posted by Spork Schivago View Post
    Why would you not recommend the second approach?
    KISS. Don't make things complicated, unless there is a good reason for it. I did add the qualification, "unless the first one cannot be made to work".

    Quote Originally Posted by Spork Schivago View Post
    Also, you're saying I should keep my .h header files in the src directory with my .c files?
    Internal header files, yes. For library header files, you could use a separate include/ directory.

    The libraries can be either statically or dynamically linked to your application. If they are statically linked, they'll become a part of your final binary, so you do not need to distribute extra files.

    If they are dynamically linked, it's better to just make them prerequisites. (This means they are listed in the package description, so that the package manager installs them if necessary. The source package will just refer to the development versions, which include the header files installed in the system location.) In this case, the header files are available in the standard system location, so you do not have those in your include/ directory.

    I'm just not familiar enough with Windows to say what makes most sense there. I guess you could include a libs/win32/ and libs/win64/ directories containing library binaries, with their development headers in include/win32/ and include/win64/. During building, you'd copy the binaries to $(BUILDDIR) , and refer to them as being in the same directory as the executable itself (so that the exact directory the binary is in does not matter much, as long as the prerequisite dynamic libraries are in that same directory too). To provide a "place" where to compile and build them from sources, I'd use something like libraries/ with a separate Makefile there, and a separate subdirectory for each library, for building the libraries. But, again, this is just my guess.

    Overall, the above could still be improved quite a bit. I don't like how we override CFLAGS and LDFLAGS; perhaps using PKGCFLAGS and PKGLDFLAGS (for whatever $(PKGCONFIG) gives us), and keeping CFLAGS and LDFLAGS empty for the user to tweak, might be better. I for one would like that make CC=gcc-4.4 CFLAGS="-O2 -fomit-frame-pointer -march=native -mtune=native" just worked.

  10. #25
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    Thank you so much! I modified it to fit my system a bit better. Because pkg-config --cflags gtk+-3.0 wouldn't print cflags that I could use, I had to reinstall mingw-64 into a directory without the (x86) (the parenthesis where throwing it off). I couldn't cross-compile on the 64-bit mingw version of the compiler. For example, with the 64-bit gcc, I couldn't make 32-bit versions of the exe. I could compile them but never could link them. It would always error out about the libraries being incompatible and fail. I didn't realize the 32-bit though could compile 64-bit versions. I asked how to do it and someone thought they remembered something about new versions not working with the -m32 stuff. Therefore, I had 2 versions of gcc installed. The 32-bit AND a separate 64-bit. I just figured if the 64-bit version couldn't create 32-bit binaries, then the 32-bit version couldn't create 64-bit versions. Boy was I wrong! Here's how I modified your Makefile:
    Code:
    GTKVER		:= 3.0
    GTKFULLVER		:= 3.6.4
    MINGWDIR		:= "C:/sdk/mingw-w32"
    SRCDIR		:= src
    BUILDDIR		:= build
    
    
    #
    # Automagic architecture detection. Override using ARCH=
    #
    ifeq ($(ARCH),)
    ifeq ($(OS),Windows_NT)
    ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
    ARCH			:= win64
    endif
    ifeq ($(PROCESSOR_ARCHITECTURE),x86)
    ARCH			:= win32
    endif
    endif
    ifeq ($(shell uname -s),Linux)
    ARCH			:= linux
    endif
    endif
    
    
    #
    # Generic defaults, possibly overridden by some architectures
    #
    PKGCONFIG		:= pkg-config
    PROGRAM_BIN	:= WHP3000_Control
    CC			:= gcc
    LD			:= $(CC)
    
    
    #
    # Architecture-specific overrides
    #
    ifeq ($(ARCH),win64)
    PKGCONFIG		:= $(MINGWDIR)/gtk+-$(GTKFULLVER)_win64/bin/pkg-config.exe
    PROGRAM_BIN	:= WHP3000_Control_x64.exe
    endif
    ifeq ($(ARCH),win32)
    PKGCONFIG		:= $(MINGWDIR)/gtk+-$(GTKFULLVER)_win32/bin/pkg-config.exe
    PROGRAM_BIN	:= WHP3000_Control_x32.exe
    endif
    
    
    #
    # Compiler and linker options
    #
    CFLAGS		:= $(shell $(PKGCONFIG) --cflags gtk+-$(GTKVER))
    LDFLAGS		:= $(shell $(PKGCONFIG) --libs gtk+-$(GTKVER))
    
    
    #
    # Architecture-specific compiler and linker overrides
    #
    ifeq ($(ARCH),win64)
    CFLAGS		+= -m64 -march=x86-64 -mtune=generic
    LDFLAGS		+= -m64 -march=x86-64 -mtune=generic
    endif
    ifeq ($(ARCH),win32)
    CFLAGS		+= -m32 -march=i686 -mtune=i686
    LDFLAGS		+= -m32 -march=i686 -mtune=i686
    endif
    
    
    #
    # Build dependencies on binaries built
    #
    PROGRAM_OBJS	:= main.o status.o
    
    
    #
    # List of programs to build
    #
    PROGS			:= $(PROGRAM_BIN)
    
    
    #
    # Recipes
    #
    
    
    .PHONY: all clean
    
    
    all: clean $(addprefix $(BUILDDIR)/, $(PROGS))
    
    
    clean:
    	rm -rf $(BUILDDIR)
    
    
    $(BUILDDIR):
    	mkdir $(BUILDDIR)
    
    
    $(BUILDDIR)/%.o: $(SRCDIR)/%.c $(BUILDDIR)
    	$(CC) $(CFLAGS) -c $< -o $@
    
    
    $(BUILDDIR)/$(PROGRAM_BIN): $(addprefix $(BUILDDIR)/, $(PROGRAM_OBJS))
    	$(LD) $^ $(LDFLAGS) -o $@
    For some reason, by default, at the command prompt atleast, in Windows, the OS is being reported as x86, instead of AMD64. I need to override each time. Is there a way we can make a rule, something like make win_all to have it compile both 32-bit and 64-bit semi-easy like? Or is this not possible? If not, I'm afraid I might want to remove the clean rule before making, just so I can make the 32-bit version, then the 64-bit, without the 32-bit getting deleted first. That's why I had, in the original Makefile, objects with different extensions, like _x86 and _x64. So we could keep track of the 32-bit objects and the 64-bit objects.

    Maybe a better way to go would be to have an x86 and a x86_64 directory inside the build and the 32-bit files get built in the x86 dir, the 64-bit get build in the x86_64? Thank you for all the help. I know it must be a real pain doing all this stuff for a total stranger. I really appreciate the help.

  11. #26
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    I mean if it's too much work, I can just keep it as is. I can make the 32-bit programs, move them out of the directory, make the 64-bit version and then move them out.

  12. #27
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by Spork Schivago View Post
    For some reason, by default, at the command prompt atleast, in Windows, the OS is being reported as x86, instead of AMD64. I need to override each time.
    I wrote it blind, so it's probably wrong. Remember, I don't have Windows. Do some web searching to see how others detect Windows variants in Makefiles.

    Quote Originally Posted by Spork Schivago View Post
    Is there a way we can make a rule, something like make win_all to have it compile both 32-bit and 64-bit semi-easy like?
    Yeah, modify the Makefile to have
    Code:
    all: $(addprefix $(BUILDDIR)/, $(PROGS))
    
    clean:
        rm -rf $(BUILDDIR)/
     
    win_all:
    	$(MAKE) ARCH=win32 clean all
    	mv -f $(BUILDDIR)/example.exe $(BUILDDIR)/example-win32.exe
    	rm -f $(BUILDDIR)/*.o
    	$(MAKE) ARCH=win64 all
    	mv -f $(BUILDDIR)/example.exe $(BUILDDIR)/example-win64.exe
    Quote Originally Posted by Spork Schivago View Post
    Maybe a better way to go would be to have an x86 and a x86_64 directory inside the build and the 32-bit files get built in the x86 dir, the 64-bit get build in the x86_64?
    It makes sense, if you usually build both.

    If you can do it without making the Makefile much messier, go for it -- build/x86 and build/x86_64 don't sound bad at all. Otherwise, I'd just use an rm -f $(BUILDDIR)/*.o to remove the object files between compiles, like in the above Makefile snippet.

    I suspect that with a bit of thought -- maybe have a sleep in between, always helps for me --, you can think of a way to make that in a simple, clean manner. I'm thinking of using different compilation and linking flags in different build subdirectories, i.e.
    Code:
    win_all: clean "$(BUILDDIR)/win32/$(PROGRAM_BIN)" "$(BUILDDIR)/win64/$(PROGRAM_BIN)"
    
    $(BUILDDIR):
    	mkdir "$(BUILDDIR)"
    
    $(BUILDDIR)/win32: $(BUILDDIR)
    	mkdir "$(BUILDDIR)/win32"
    
    $(BUILDDIR)/win32/%.o: $(SRCDIR)/%.c $(BUILDDIR)/win32
    	$(CC) $(WIN32CFLAGS) $(CFLAGS) $< -o $@
    
    $(BUILDDIR)/win32/$(PROGRAM_BIN): $(addprefix $(BUILDDIR)/win32/, $(PROGRAM_OBJS))
    	$(LD) $^ $(WIN32LDFLAGS) $(LDFLAGS) -o $@
    
    $(BUILDDIR)/win64: $(BUILDDIR)
    	mkdir "$(BUILDDIR)/win64"
    
    $(BUILDDIR)/win64/%.o: $(SRCDIR)/%.c $(BUILDDIR)/win64
    	$(CC) $(WIN64CFLAGS) $(CFLAGS) $< -o $@
    
    $(BUILDDIR)/win64/$(PROGRAM_BIN): $(addprefix $(BUILDDIR)/win64/, $(PROGRAM_OBJS))
    	$(LD) $^ $(WIN64LDFLAGS) $(LDFLAGS) -o $@
    which might make everything simpler, because then you could specify both win32 and win64 overrides in a single make command.

    So, yeah, arch-specific subdirectories under build/ do make sense, as long as you can make it simple enough. KISS, again.

    Quote Originally Posted by Spork Schivago View Post
    I know it must be a real pain doing all this stuff for a total stranger.
    I wouldn't be here if it was; I only do this for fun.

  13. #28
    Registered User migf1's Avatar
    Join Date
    May 2013
    Location
    Athens, Greece
    Posts
    385
    Advanced makefiles isn't my strong pointer either, so I think it would be easier to just have 2 separate makefiles, one for x86 builds and one for x64 builds. I think this approach would yield in both makefiles being much simpler.

    "make -f makefile_x86" could build into a "build/x86" subdirectory,
    and
    "make -f makefile_x64" could build into a "build/x64" subdirectory.

    Also, on Windows it is always recommended to install mingw and friends on folders that do NOT contain spaces in their pathname, so you don't have to use double quotes when trying to access them via scripts.

    As for the 3rd-party libraries, personally I would compile them once on both platforms and then just use their binaries and header files via gcc's -L and -I command-line flags. You may indeed put them in their own subdirectory (lets say "libs/bin" and "libs/include"), but there's no need to recompile them or even keep around their source code. Again, you may keep x86 and x64 variants in different subdirectories, lets say "libs/x86" and "libs/x64". makefile_x86 will use the former and makefile_x64 will use the latter.

    PS1. Btw, I was the one who told you that mingw-w64's -m32 flag has been deprecated in recent versions of mingw-w64. However, I encouraged you to research yourself, because it's been a long time since the last time I dealt with that stuff (so I wasn't sure). But anyway I had no idea that that -m64 still works! Nice info!

    PS2. Consider switching from GTK+3 to GTK+2. Again I cannot be sure, but I think that by doing so you'll make your life easier when it comes to Windows.
    "Talk is cheap, show me the code" - Linus Torvalds

  14. #29
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    Quote Originally Posted by migf1 View Post
    Advanced makefiles isn't my strong pointer either, so I think it would be easier to just have 2 separate makefiles, one for x86 builds and one for x64 builds. I think this approach would yield in both makefiles being much simpler.

    "make -f makefile_x86" could build into a "build/x86" subdirectory,
    and
    "make -f makefile_x64" could build into a "build/x64" subdirectory.

    Also, on Windows it is always recommended to install mingw and friends on folders that do NOT contain spaces in their pathname, so you don't have to use double quotes when trying to access them via scripts.

    As for the 3rd-party libraries, personally I would compile them once on both platforms and then just use their binaries and header files via gcc's -L and -I command-line flags. You may indeed put them in their own subdirectory (lets say "libs/bin" and "libs/include"), but there's no need to recompile them or even keep around their source code. Again, you may keep x86 and x64 variants in different subdirectories, lets say "libs/x86" and "libs/x64". makefile_x86 will use the former and makefile_x64 will use the latter.

    PS1. Btw, I was the one who told you that mingw-w64's -m32 flag has been deprecated in recent versions of mingw-w64. However, I encouraged you to research yourself, because it's been a long time since the last time I dealt with that stuff (so I wasn't sure). But anyway I had no idea that that -m64 still works! Nice info!

    PS2. Consider switching from GTK+3 to GTK+2. Again I cannot be sure, but I think that by doing so you'll make your life easier when it comes to Windows.
    With the whole mingw-w64's -m32 flag not working, you were absolutely right about it. I was trying to write the sentence in such a way where it didn't sound like I was given false information. I cannot cross-compile using the 64-bit compiler (I cannot go from a 64-bit compiler to a 32-bit executable). I just assumed I couldn't go from a 32-bit compiler to a 64-bit compiler as well. It was real surprising when it actually worked. I did try researching it. I couldn't find anything on it really. Perhaps I'm just getting burned out a little bit. A good nights sleep seems to make a world of difference! Bugs that seem impossible to track down or stuff that magically stops working for no reason, just seem to disappear with the start of a new day. Like oh, duh! Of course x is undefined! We have it set to y but we never set y! Duh!

    I'm thinking maybe the reason the 64-bit compiler doesn't cross-compile to 32-bit executables is because it's a bug. If I use the -c option, I can create object files, 32-bit, no problems. There are libraries in the 64-bit version that have stuff like lib_32-bit_blah or something like that. I don't have it installed anymore, but it does seem like something just broke some wheres. Compiling works fine, linking doesn't. I'm pretty sure they said the 64-bit version is in beta stage anyway.

    Also, why do you think I should use GTK+-2 instead of 3? I know no GTK+. So I would think it'd be best to learn the newer stuff rather than the old.


    Oh, also, I forgot to say, I really don't want to use multiple Makefiles if I can help it. There's also the Linux builds, which would mean 3 Makefiles. For MinGW64, for the default install directory, they pick C:\Program Files\... for 64-bit MinGW or for the 32-bit GCC on a 64-bit OS, the default is C:\Program Files (x86)\...

    They should change this. Granted, the MinGW stuff works fine in those directories, but installing GTK+ in there only works with the (x86) stuff if you don't use pkg-config.
    Last edited by Spork Schivago; 08-25-2015 at 11:28 AM.

  15. #30
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    And thanks to the kind people on the MinGW64-w32 mailing list, I think I have found some new ideas as to why I cannot compile 32-bit EXEs with the 64-bit compiler.
    Ray Donnelly was kind enough to say:
    " There's a good reason not to use -m32 and -m64. You want to use SEH
    for Win64 since it's fastest but you can only use sjlj or dwarf2
    exceptions for Win32. Making a 'multilib' MinGW-w64 GCC forces the
    same exception model on both."

    And he's definitely correct here. I'm guessing by using the -m64 option on the 32-bit compiler, my 64-bit exe that is being created is in fact using the SJLJ exception handling. If I were to create the EXE using the 64-bit compiler, it'd use the SEH exception handling, which would be the ultimate way to go. I don't know much about the exception handling options, but I researched it and everything I've read say if SEH is available, use it. It's faster, it's more native, etc. Perhaps I should go back to having both compiler's installed and then using the 64-bit one for 64-bit compiles, 32-bit one for 32-bit compiles. This would complicate the Makefile even more though. Especially with a win_all. Maybe I can set a CC_32 and a CC_64 variable?


Popular pages Recent additions subscribe to a feed

Similar Threads

  1. capturing keystroke from keyboard
    By bepof in forum C Programming
    Replies: 6
    Last Post: 06-12-2013, 10:51 AM
  2. Capturing keyboard input, one character at a time
    By Paul Omans in forum C Programming
    Replies: 17
    Last Post: 05-31-2013, 03:57 PM
  3. Capturing keyboard activity
    By Trooper88 in forum C Programming
    Replies: 2
    Last Post: 02-11-2012, 05:27 PM
  4. Replies: 5
    Last Post: 05-05-2010, 04:24 AM
  5. keyboard capturing
    By xlnk in forum Linux Programming
    Replies: 4
    Last Post: 01-31-2003, 01:02 PM