0

I'm generating a .c file with global string variable from .make file and compile it into the static library. After linking that library to the shared library, global string symbol is missing, because it wasn't used in the library. How to forcibly link that specific object to the dynamic library, or use that string so the symbol will be added to the shared lib.

I've tried to generate another .c file from shared library makefile, but no result. I need that string to show up in shared lib's .data section.

Static lib's generated file

#ifndef _teststatic
#define _teststatic
#endif

char __test_static_string[] = "This string is in static lib.";

Shared lib's generated file

#ifndef _testshared
#define _testshared
#endif

char __test_shared_string[] = "This string is in shared lib.";
extern char __test_static_string[];

.data section of the shared library

Contents of section .data:
 264f20 204f2600 00000000 00000000 00000000   O&.............
 264f30 00000000 00000000 00000000 00000000  ................
 264f40 00000000 00000000 00000000 00000000  ................
 264f50 e61d1f00 00000000 f31d1f00 00000000  ................
 264f60 0a1e1f00 00000000 191e1f00 00000000  ................
 264f70 54686973 20737472 696e6720 69732069  This string is i
 264f80 6e207368 61726564 206c6962 2e00      n shared lib.. 

Using gcc flag

--whole-archive

is no option.

  • Unrelated, but could protect you from a butt-load of pain later: [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) – user4581301 Apr 06 '21 at 22:06
  • Does this work: [prevent gcc from removing an unused variable](https://stackoverflow.com/questions/29545191/prevent-gcc-from-removing-an-unused-variable)? – mkayaalp Apr 06 '21 at 22:09
  • Hi @mkayaalp, in that case string was lost during the optimization, but in mine during the linking process. I've tried adding __attribute__((used)) " char test_static_string[] __attribute__((used)) = "This string is in static lib."; " but it didn't help. – Narek Jaghinyan Apr 07 '21 at 06:28
  • @NarekJaghinyan How about this: [how to prevent linker from discarding a function?](https://stackoverflow.com/questions/53985290/how-to-prevent-linker-from-discarding-a-function) – mkayaalp Apr 07 '21 at 10:56
  • I've figured it out, just needed to use at least one symbol from static libs generated file in shared libs code to create dependency to that particular object. For example: void dummy_funciton(void); void dummy_funciton() { printf(test_static_string); } This method will also work for nested static libraries. I will add an answer to this thread next week. – Narek Jaghinyan Apr 09 '21 at 06:30

2 Answers2

0

Static lib's generated file

#ifndef _teststatic
#define _teststatic
#endif

char test_static_string[] = "This string is in static lib.";

Shared lib's generated file

#ifndef _testshared
#define _testshared
#endif

#include <stdio.h>

char test_shared_string[] = "This string is in shared lib.";
extern char test_static_string[];

void dummy_function
{
    printf(test_static_string);
}

In this case printf forces linker to link static lib's generated file's object and all global strings appear in shlibs .data section.

This method also works for "nested" static libs.

0

I've found another - better way to do this.

 char mystring[] = "This is generated string";
 
 void foo()
 {
     (void)mystring;
 }

This one works for header files(probably will work for cpp files too).

char __attribute__((weak)) mystring[] = "This string is in static
lib.";

for windows:

char __declspec(selectany) mystring[] = "This string is in static
lib."; // this one may be optimized based on provided flags, haven't
tested thoroughly.