Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there good tips or tools for removing third party C and C++ libraries from a codebase? (OS X or Linux)

I am in the process of reducing and quarantining my usage of some libraries. Many existing programs I've written use these libraries directly. I would like the compiler (GCC and/or Clang in this case) or some tool to help me identify these uses across my codebase. In short, I would like to poison use of these libraries across the codebase, with the exception that they will be used by one library, and that one library will be visible to other modules in my codebase.

The Question:

1) Do you know of tools which can help me with this?

2) or can you recommend some strategies to make this process easier?

Conditions and Details:

  • Deleting their includes is not an option.
  • Search is not effective due to the size of my codebase and the count of symbols I want to quarantine.
  • Use of refactoring tools will be too tedious, given the complexity of the codebase and the number of symbols to remove.
  • Deprecating symbols individually is not an option due to the number of declarations in the third party libraries.
  • The third party library interfaces are written mostly in C.
  • The translations will be C++ and Objective-C++.
  • Preprocessor trickery is not elegant for the way my builds are configured, and it would alter too many files.
  • Every last use does not need to be eliminated. Ideally, they would be, but most uses is satisfactory. This is not a requirement simply because there is too much to update.
  • Removing them from the link stage is not a good option in this case (detailed in Update #3).
  • Ideally, this tool or strategy would be available on OS X, but I can also build a significant chunk of the programs targeting Linux.

Some strategies that have come to mind:

The best I have come up with so far for this case is to redeclare the types the library uses, and to decorate them with deprecated attributes:

typedef IHREType IHREType __attribute__((__deprecated__));

But that's won't cover all cases, and the signal to noise ratio will be quite high after a few iterations.

An alternative would be to redeclare these types in the root namespaces I use:

namespace MON {
typedef t_poisoned IHREType;
}

but that will become a bit messy.

So I figure I will start with the deprecated attribute strategy, but before I do that, I figure somebody else would have already solved this problem and would know of a better solution.

Update #1

  • K-ballo mentioned a good strategy (Poisoning via inclusion). Unfortunately, it will not work in my case the APIs I'd like to quarantine are also found in system frameworks which are included via APIs I do not wish to quarantine.

Update #2

Added Linux due to the low number of responses.

Update #3

> > Justin: Removing them from the link stage is not a good option in this case.
> thiton: Why not? 

To elaborate on this point: I like the way the libraries and projects are laid out at this time. There is a combination of static and dynamic libraries. Altering that structure and synchronizing the dependencies is time consuming (although isolated cases may be a good use of time for some of the libraries...). The linker also resolves a good amount of the symbols I want to remove due to dependencies (e.g. in system libraries).

The plan I have approaching this

There are hundreds of Xcode projects in the codebase (add to that projects for other builders/IDEs).

I will focus on these updates for a few days here, and a few days there; 100% coverage is not a realistic goal for this timeframe, nor is it currently a requirement. Due to the size of the task and the current state of the codebase, I'd like to focus on removing occurences by number at this time. Removing by number is also preferable because it will ultimately result in less time building (it takes a while to build this all out). Once that is reduced, I will turn to complete elimination - at least, that is my current plan. In this case, I have time to perform the updates, but it is not yet urgent. If your recommendation deviates from this model, I do have flexibility.

like image 624
justin Avatar asked Oct 21 '11 05:10

justin


2 Answers

I would provide a shallow version of the includes with an #error or #warning directive so that the preprocessor would let me know who is using those files.

like image 140
K-ballo Avatar answered Sep 30 '22 17:09

K-ballo


You might use the #pragma GCC poison identifier directive to ask GCC to warn about further uses of the given identifier

You can also use the __attribute__((deprecated)) (in GCC) for similar goals.

If your code base is large enough to make the effort worthwhile, you could develop a GCC 4.6 plugin (or a GCC MELT extension, to do what you want. (MELT is a high-level domain specific language to extend GCC).

And a GCC plugin (painfully coded in C) or MELT extension (more easily coded in MELT) could behave to insert these attributes or #pragma for you.

But automating such tasks is worthwhile only for a not too small code base.

like image 24
Basile Starynkevitch Avatar answered Sep 30 '22 19:09

Basile Starynkevitch