Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: Very Close to Finishing Linux Port

In last week’s report, I had figured out that my installation of Docker was missing some of the newer features available, which explained why I had to do so much more work to do what seemed like a simple thing.

This week, I managed to make great progress on my port work.

Sprint 59: Ports

Planned and Incomplete:

  • Create Linux port

My work was split up into the following tasks:

  • T: Use bind mount to load current project and relevant Projects directories as read-only
  • T: Build custom libraries for 32-bit
  • T: Build custom libraries for 64-bit
  • T: Build game using libraries for 32-bit
  • T: Build game using libraries for 64-bit
  • T: Update Cmake files to package up assets correctly
  • T: Write script to coordinate all of the tasks to put together a finished binary with 64-bit and 32-bit support

I once again put in more hours than expected, and I successfully built custom SDL2 libraries in both 64-bit and 32-bit varieties.

As I’ve mentioned, I am trying to use an older version of Debian to build my code because I want the resulting binaries to run on as many Linux-based distributions as I can.

So I have been using debian/eol:etch as a base image, but I quickly discovered that the version of CMake available in Etch is v2.4.5, which is too old for some of the features my CMake-related scripts needed.

I tried Debian Lenny, which has a CMake at v2.6, but it turns out that the FindSDL2.cmake that I was using has a QUIET keyword that it didn’t know about.

So I switched to Debian Squeeze, which has a CMake at v2.8.2, which seemed fine. I did run into an issue in which I thought there was yet another compatibility problem, but it turned out to be a problem with an environment variable not actually being passed in.

In trying to build my custom libraries, I have this section in my CustomLibs.cmake:

# Extract SDL2 into build directory (assume only one tarball exists).
# Creates ${SDL2_EXTRACTED_DIR}/build/.libs/libSDL2.so files.
    FILE (GLOB SDL2_TARBALL "${THIRD_PARTY_LIB_DIR}/SDL2-*.tar.gz")
    EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E tar xzf "${SDL2_TARBALL}" WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/")
    STRING(REGEX REPLACE "^.*(SDL2-[A-Za-z0-9.]+).tar.gz*$" "\\1" SDL2_EXTRACTED_DIR ${SDL2_TARBALL})

And I was getting an error along the lines of:

string sub-command REGEX, mode REPLACE needs at least 6 arguments total to command.

Oh, was this something else that has changed? CMake’s documentation doesn’t seem to indicate anything. I spent quite some time trying to track down what was going on, eventually upgrading to Debian Wheezy before deciding I could downgrade again to Squeeze.

Eventually, I figured out that THIRD_PARTY_LIB_DIR wasn’t set to anything, and so SDL2_TARBALL was similarly not set correctly, which meant the remaining commands were not able to execute properly.

Before this porting work, I had a toolchain file that set THIRD_PARTY_LIB_DIR to a particular directory on my machine that had the SDL2 library’s tarball. That is, a CMake-specific toolchain file set the variable, which meant that the CMakeLists.txt and other files knew about that variable.

Obviously that specific path won’t work inside the Docker container, so I wanted to set that library by use of an environment variable. And I struggled to figure out why my Docker container’s CMD line seemed to be able to output the ENV variable, and the script being called seemed to be able to output the variable, but CMake seemed ignorant of it.

Well, I realized that within my CMakeLists.txt and CustomLibs.cmake, I never needed to pay attention to environment variables before, as I was using that toolchain file to set the variable.

In order to make use of an environment variable, I had to do the following:

IF (NOT DEFINED ENV{THIRD_PARTY_LIB_DIR})
    MESSAGE(FATAL_ERROR "THIRD_PARTY_LIB_DIR is not defined.")
ELSE()
    SET(THIRD_PARTY_LIB_DIR $ENV{THIRD_PARTY_LIB_DIR})
    MESSAGE("THIRD_PARTY_LIB_DIR is defined as ${THIRD_PARTY_LIB_DIR}")
ENDIF()

Note that in the IF statement, I can refer to the environment variable with ENV, but in the SET statement, I need to use a dollar sign to refer to it.

Once I figured that issue out, I found that I needed to install libxext-dev because otherwise SDL2 wasn’t going to build.

Then I ran into a different environment variable being missing, so I solved it similarly to the way I did it above.

And then I ran into a frustrating problem.

My custom libraries get built by extracting the tarballs for various SDL2-related libraries. When SDL2_image got extracted, I then run configure on it with some custom arguments to get as small a binary as I can, then build it.

Except I kept getting the following error:

 aclocal-1.16: command not found
WARNING: 'aclocal-1.16' is missing on your system.
         You should only need it if you modified 'acinclude.m4' or
         'configure.ac' or m4 files included by 'configure.ac'.
         The 'aclocal' program is part of the GNU Automake package:
         <https://www.gnu.org/software/automake>
         It also requires GNU Autoconf, GNU m4 and Perl in order to run:
         <https://www.gnu.org/software/autoconf>
         <https://www.gnu.org/software/m4/>
         <https://www.perl.org/>

I tried installing automake, then wondered if I needed to install a bunch of other automake-related tools separately, but then I came across this Stack Overflow response that pointed me in the right direction:

It defeats the point of Autotools if GNU This and GNU That has to be installed on the system for it to work.

As well as this response:

As the error message hint at, aclocal-1.15 should only be required if you modified files that were used to generate aclocal.m4

If you don’t modify any of those files (including configure.ac) then you should not need to have aclocal-1.15.

In my case, the problem was not that any of those files was modified but somehow the timestamp on configure.ac was 6 minutes later compared to aclocal.m4.

So I checked, and I see that the directory that SDL2_image was being extracted to had files with timestamps that reflect my system’s current time.

If I manually extracted those files on my host system instead of within the Docker container, the timestamps show 2019 as the year, meaning that whatever files were in the tarball, the timestamps of those files were getting preserved.

So either Docker bind mounts do something wacky with timestamps, similar to how virtual machine shared drives can get kind of iffy, or maybe there was a compatibility issue with tar just like how I was dealing with compatibility issues with CMake.

And sure enough, I found that in tar v1.26 around 2011, tar’s –atime-preserve option had a major fix to make it work correctly.

So once again, I upgraded my Docker image to use Debian Wheezy as a base image, and tar was suddenly extracting files with preserved timestamps, which meant that it no longer was asking me to have automake installed.

And the rest of my build scripts were successfully able to build and package up the custom libraries! Woo!

So the next piece to work on was similar. I had to update my scripts to accept environment variables and such, and then I could build the Toy Factory Fixer project just fine.

And the only reason that it isn’t finished yet? I ran out of time in the week. Basically, I ran into an error due to code that requires C++11 compatibility, and Debian Wheezy is using GCC 4.7, which would require the use of a –std=c++0x flag for compatibility.

So either I change my code or I pursue that flag, which I think might require me to install an updated libstdc++, and at that point, why not just upgrade to Debian Jessie?

Either way, I expect that my project will successfully build soon, and then I can work on making sure that my CMake packaging-related lines understand how I’ve created separate directories for my resource files since the last time I worked on it years ago.

After that, I want to make sure all of the library building, project building, and packaging into a single tarball to distribute becomes a one-line script.

And then the port will be done.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!

One reply on “Freshly Squeezed Progress Report: Very Close to Finishing Linux Port”

Leave a Reply

Your email address will not be published.