-3

I'm working on a C static library that's eventually going to be open-source, so I'm cross-compiling on Windows and Ubuntu to backstop for any portability issues.

The problem I'm having is that the symbols from one of the object files are omitted from the Linux build. When I build the library using VS2015 on Windows, all symbols are present.

I'm mostly used to developing for Windows, so I'm pretty spoiled to using an IDE for most build scenarios. On Ubuntu, I'm using NetBeans , and I'm not sure if the problem is with my understanding of gcc or if I don't have NetBeans set up correctly.

Details

Ubuntu 16.04LTS using gcc(Ubuntu) 5.4.0

NetBeans IDE 8.1 C/C++

The library consists of 3 source files and 2 header files:

queue.c  --> queue implementation
memutil.c  --> memory utilities
mylib.c  --> main library implementation

queue.h  --> included by queue.c and mylib.c
mylib.h  --> header file for the static library

The mylib.h header contains the header information for the memutil.c source file, wrapped in a conditional that depends on the MEMCHECK symbol on the command line. Likewise for the code in the memutil.c source file. The MEMCHECK symbol is defined when building the library, but when I run nm on libmylib.a after the Linux build, no symbols are listed for the memutil.o object file. When i look at the mylib.lib file on Windows, all the symbols for memutil.obj are listed.

Now, if I add a stubbed out source file that just includes the mylib.h header, all of the symbols are present in the libmylib.a library. I'm guessing there's some sort of header file interaction malfunction going on, but I don't where to look to find out what it is or how to fix it. I have Google'd the snot out of this with as many different phrasings as I can think of, but no joy.

Here's the NetBeans build output, less all of the directory noise:

gcc    -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/queue.o.d" -o build/queue.o queue.c
gcc    -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/memutil.o.d" -o build/memutil.o memutil.c
gcc    -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/mylib.o.d" -o build/mylib.o mylib.c

ar -rv dist/Debug/GNU-Linux/libmylib.a build/queue.o build/memutil.o build/mylib.o 
ar: creating dist/Debug/GNU-Linux/libmylib.a
a - build/queue.o
a - build/memutil.o
a - build/mylib.o
ranlib dist/Debug/GNU-Linux/libmylib.a

BUILD SUCCESSFUL (total time: 3s)

Stubbing in the header file inclusion can't be the fix for this, can it? It works, but it seems awfully crude. Besides, I can't really credit that it would be necessary with gcc and not necessary with VS2015.

Mark Benningfield
  • 2,800
  • 9
  • 31
  • 31
  • 1
    It can get a little hairy, but you might consider compiling with the `-E` option. This will show the source code after the preprocessor has run, so you should be able to see whether or not `-DMEMCHECK` is doing what you think it should be doing. Your code will be towards the end after the `#include`s. You can redirect the output to a file, `gcc -E code.c > ppCode.c` https://stackoverflow.com/questions/3742822/preprocessor-output – yano Dec 27 '17 at 06:22
  • also recommend compiling with the `-Wextra` flag to turn on more warnings. – yano Dec 27 '17 at 06:27
  • @yano: It seems to me that if there were a problem with the conditional, the Windows build would be wonky as well. – Mark Benningfield Dec 27 '17 at 21:14
  • That would make the most sense certainly, but clearly something is happening. IDEs can #define stuff behind the scenes, who knows? Wouldn't bet my next paycheck that's the problem, but worth a look IMO. Just another variable in the chain to eliminate. – yano Dec 27 '17 at 21:27

1 Answers1

0

Well, I found the solution, but I'm not marking this as the accepted answer because I'm not sure exactly why it's the solution.

I noticed the -Mxx flags on the compiler lines:

gcc    -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/...

So I went back to Google and found this site: Auto-Dependency Generation, which covers having Make handle the generation and tracking of build dependencies.

Then I starting combing through every single menu item in NetBeans until I found this one:

Tools->Options->C/C++->[on/off] Enable dependency checking in generated makefiles

I cleared that switch, and all of the missing symbols appeared in the library. However, the -Mxx flags were still present on the compiler lines in the build output. Now, the makefile generation for NetBeans uses about 5 separate makefile templates and 3 or 4 different XML configuration files to generate the makefile at build time, based on build configuration and target. I couldn't figure out if the auto-dependency flags were rendered inert by flipping that switch or not.

But, if I'm reading the information on the above-mentioned website correctly, those -Mxx flags are actually used by gcc in support of Make, so I'm not sure how they would have a different interpretation based on something that NetBeans did. Although, there are a LOT of substitutions in those makefile templates, and with me not being an Autoconfig/Make wizard, I may have simply missed it.

So, apparently, since none of the source files actually included the function prototypes for the memory utilities -- because they are contained in the library header file, which none of the library source files include (it's meant for inclusion by client code) -- the NetBeans dependency checker decided that those functions weren't needed in the library.

Mark Benningfield
  • 2,800
  • 9
  • 31
  • 31