natille
natille

Reputation: 61

MinGW C++ Linker unable to find file due to truncating filename and/or unable to find definitions

I'm experiencing a very bizarre linker problem that exhibits in different ways in different scenarios. Unfortunately, I cannot share any source, so this is a little bit of a long shot, but I'm lacking in ideas to track this down.

I'm trying to build unit tests for our project that will run in a Windows environment (so excluding hardware dependent functionality). We also build the same unit tests such that they will run on our target (Renesas PK-S5D9), therefore using a different compiler, and it is successful. Note that we are using gtest and it's included as source, not as a library. There are no libraries involved in this build, only source.

Scenarios:

  1. Work was being done on a branch. Develop was updated, so the developer merged in the new HEAD. Upon doing this, an unrelated test started failing to link; let's call the test ATest.cpp and the product source A.cpp/h. The linker complains that the functions declared in A.h and used by ATest.cpp are undefined, however, the build of A.cpp was successful, the .o exists in the expected location, and the .o is listed in the linking command.
  2. I took the head of the branch and excluded the files the merge from develop brought in (one class and one test) and got a different error. The end of the preceding line contains the file "./product/adapters/ActionableProvider.o", which looks to be getting truncated when g++ tries to access it:

TruncationOfActionableProvider.o

  1. I took develop and piecemeal added content from the branch (a handful of changes and a new class with a test). When I got nearly through it, I got a similar error to that listed in scenario 2. I tried commenting out all the content of the function that was implemented in the class, and the truncation reduced:

ReducedTruncationOfActionableProvider.o

Things that add to the weird:

The commits where the failure was observed by developers do NOT fail when running using the same toolset but on our build server (slightly different Windows 10 build and also does not have heavy anti-virus because it's segmented off in our internal network).

Any thoughts that lead to something more to try to piece this mystery together are welcomed!

Upvotes: 0

Views: 218

Answers (1)

natille
natille

Reputation: 61

Had an epiphany moment. It's a command length limit problem. Apparently Windows can only handle 8192 characters in a command, hence the truncated filename. Here's one reference: https://mcuoneclipse.com/2015/03/29/solving-the-8192-character-command-line-limit-on-windows/

Our final solution was to modify our linker command in e2studio (eclipse) from:

${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}

to:

@$(file >link_cmd.in,${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}) ${COMMAND} @"link_cmd.in"

Steps in the journey included coming up with a list of possible solutions (if only we could figure out how to implement them :)):

  • shorten paths
  • make a library
  • figure out how to get eclipse to build test_desktop in a different shell that doesn't have this problem
  • figure out how to get eclipse to make the linker command use a file (see @file option in https://linux.die.net/man/1/g++)

We favored the last solution, but we only realized it because that's how our target specific unit tests circumvented the problem. Some searching brought us to https://www.eclipse.org/forums/index.php/t/369721/ where the last post was someone indicating they posted a workaround to the bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=72965. A big thanks to Corneliu Zuzu!! After some initial evaluation, we realized we just needed to dump the command to a file using a similar mechanism (it seems Corneliu Zuzu had a more challenging problem that included backwards slashes?). Hence the above solution.

Upvotes: 1

Related Questions