cmake builds are using the default gme_types.h, not the generated one

Issue #38 new
Pietro Gagliardi created an issue

Trying to build a subset of game-music-emu as a static library for a personal project, and it appears that all cores are unconditionally included in the final build’s gme_types_list() function. Example reproducer:

$ mkdir /tmp/gme
$ cd /tmp/gme
$ git clone --quiet https://bitbucket.org/mpyne/game-music-emu.git
$ mkdir build prefix
$ cmake -B /tmp/gme/build -S /tmp/gme/game-music-emu -DCMAKE_SYSTEM_PREFIX_PATH='/usr;/usr/local' -DCMAKE_INSTALL_PREFIX="/tmp/gme/prefix" -DBUILD_FRAMEWORK=OFF -DENABLE_UBSAN=OFF -DBUILD_SHARED_LIBS=OFF -DUSE_GME_AY=0 -DUSE_GME_GBS=1 -DUSE_GME_GYM=0 -DUSE_GME_HES=0 -DUSE_GME_KSS=0 -DUSE_GME_NSF=0 -DUSE_GME_NSFE=0 -DUSE_GME_SAP=0 -DUSE_GME_SPC=0 -DUSE_GME_VGM=0 > cmake.conf.out 2>&1
$ cmake --build /tmp/gme/build > cmake.make.out 2>&1
$ cmake --install /tmp/gme/build > cmake.install.out 2>&1
$ c++ game-music-emu/demo/basics.c game-music-emu/demo/Wave_Writer.cpp -o basics -lz -I prefix/include prefix/lib/libgme.a 
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
Undefined symbols for architecture x86_64:
  "_gme_ay_type", referenced from:
      _gme_type_list in libgme.a(gme.cpp.o)
  "_gme_gym_type", referenced from:
      _gme_type_list in libgme.a(gme.cpp.o)
  "_gme_hes_type", referenced from:
      _gme_type_list in libgme.a(gme.cpp.o)
  "_gme_kss_type", referenced from:
      _gme_type_list in libgme.a(gme.cpp.o)
  "_gme_nsf_type", referenced from:
      _gme_type_list in libgme.a(gme.cpp.o)
  "_gme_nsfe_type", referenced from:
      _gme_type_list in libgme.a(gme.cpp.o)
  "_gme_sap_type", referenced from:
      _gme_type_list in libgme.a(gme.cpp.o)
  "_gme_spc_type", referenced from:
      _gme_type_list in libgme.a(gme.cpp.o)
  "_gme_vgm_type", referenced from:
      _gme_type_list in libgme.a(gme.cpp.o)
  "_gme_vgz_type", referenced from:
      _gme_type_list in libgme.a(gme.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The gme_types.h in the cmake build folder has the macros defined correctly, so I’m guessing it’s using the gme_types.h provided in the repository, which is explicitly marked as

 * This is a default gme_types.h for use when *not* using
 * CMake.  If CMake is in use gme_types.h.in will be
 * processed instead.

I can provide any of the outputs of my run above if needed.

System:
macOS 10.12.6
Xcode 9.2 (9C40b)
cmake version 3.16.4 from MacPorts

Comments (3)

  1. Pietro Gagliardi reporter

    Okay I figured out what’s going on: simply having the fallback gme_types.h in the same directory as the source file that includes it causes gcc and clang (and MSVC too, upon further research) to prioritize that over any gme_types.h in any of the -I-specified folders. Here’s a simple reproducer that works on both macOS and Linux:

    $ mkdir /tmp/abc; cd /tmp/abc
    $ mkdir a b
    $ echo '#error a' > a/header.h
    $ echo '#error b' > b/header.h
    $ echo '#include "header.h"' > a/file.c
    $ cc -o /dev/null -I /tmp/abc/b a/file.c 
    

    I’m not sure what the best way to fix this is. I can’t find a compiler option to let you move the same-directory search to later in the header file search order, so I’m not sure if this can be fixed cleanly.

    The best I can think of: Since it appears the generated gme_types.h isn’t supposed to be installed to the installation prefix, you could possibly alter the cmake build process to define an additional macro to indicate that it generated the file. You would then give both the generated file and the fallback file different filenames, and have gme_types.h just include the appropriate one based on that macro.

    In the meantime, I’ll just delete the fallback gme_types.h before my local builds.

  2. mywave

    Best is probably to rename gme_types.h into gme_types.h.example

    Other build-systems should generate or provide their own gme_types.h.

  3. Log in to comment