0

[As Cornstalks explained below, I'm trying to strip a header prefix that's used in an #include. So it appears this question is not a duplicate of How to make g++ search for header files in a specific directory?]

I'm making some changes to a library. I have the library locally, so its not installed in its customary system location.

I have a test source file and its sided-by-side with the library. The test file has a bunch of includes like:

#include <foo/libfoo.h>

And it also has a bunch of customary includes, like:

#include <iostream>

I'm trying to compile the test file using:

$ g++ ecies-test.c++ -I. -o ecies-test.exe ./libcryptopp.a

And (the space between -iquote . does not appear to make a difference):

$ g++ ecies-test.c++ -I. -iquote . -o ecies-test.exe ./libcryptopp.a

The problem I am having is I don't know how to tell g++ that <foo/libfoo.h> means "./libfoo.h". Effectively, I'm trying to strip the prefix used to include the header. I've looked in the manual under 2.3 Search Path, but it does not really discuss this scenario.

I have about 60 extra test files I use for the library. And each has 10 or 20 includes like this. So I can't go through and change #include <foo/libfoo.h> to #include "./libfoo.h" in 500 or 600 places.

I tried @rici's work around by creating the fictitious directory structure, but it broke GDB debugging. GDB cannot find symbols for class members, so I can't set breakpoints to debug the code I am attempting to modify.

How do I tell the compiler to look in PWD for system includes?


Below is a typical error. ECIES_FIPS is in my local copy of the library.

$ g++ -DNDEBUG=1 -g3 -Os -Wall -Wextra -I. -iquote . ecies-test.c++ -o ecies-test.exe ./libcryptopp.a
ecies-test.c++:29:17: error: no member named 'ECIES_FIPS' in namespace
      'CryptoPP'
using CryptoPP::ECIES_FIPS;
      ~~~~~~~~~~^
ecies-test.c++:44:5: error: use of undeclared identifier 'ECIES_FIPS'
    ECIES_FIPS<ECP>::Decryptor decryptor(prng, ASN1::secp256r1());
    ^
ecies-test.c++:44:16: error: 'ECP' does not refer to a value
    ECIES_FIPS<ECP>::Decryptor decryptor(prng, ASN1::secp256r1());
               ^
/usr/local/include/cryptopp/ecp.h:30:20: note: declared here
class CRYPTOPP_DLL ECP : public AbstractGroup<ECPPoint>
    ...

In case it matters:

$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin12.6.0
Thread model: posix
Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • Is the current directory (`.`) named `foo`? If so, you could change it to `-I..`. Alternatively, you could symlink `foo` to `.`. I don't know how to tell the compiler to map the path`foo/*` to `./*`, but those might be viable workarounds. – Cornstalks Apr 19 '15 at 02:14
  • 2
    The "I" option should give you what you need though. Here's a previous SO question that might help : http://stackoverflow.com/questions/12654013/how-to-make-g-search-for-header-files-in-a-specific-directory – Corb3nik Apr 19 '15 at 02:16
  • Thanks @Cubia - I'm not sure why searching did not uncover that question. I cast the first close-as-duplicate vote. – jww Apr 19 '15 at 02:18
  • @Cornstalks - I'd like to, but I have the real library named `foo` there. – jww Apr 19 '15 at 02:19
  • @jww You're welcome, I flagged this as duplicate. – Corb3nik Apr 19 '15 at 02:19
  • Are you sure this is a duplicate? Because you say you want `foo/libfoo.h` to translate to `./libfoo.h`, which `-I` doesn't handle. That `foo/` part is part of the file path that the compiler will use to find the header file, and you've asked how to strip it out (which isn't what that other question asks). – Cornstalks Apr 19 '15 at 02:24
  • @Cornstalks - yeah, as I read the question and solutions, it appears its not a duplicate. The question was slightly different, and the answers reflected it. Maybe I should withdrawal the dup vote. – jww Apr 19 '15 at 02:25
  • 1
    @jww Is it possible to just add a folder called "foo" and place your "libfoo.h" file inside? The header prefix would still be there though, but you won't have to change any of your code. – Corb3nik Apr 19 '15 at 02:28
  • @Cubia - I tried creating the fake `foo` directory and placing the library files in it, but it broke GDB debugging. GDB cannot find symbols of class members, so I can't set breakpoints to debug the functions I am trying to modify. – jww Apr 19 '15 at 05:38
  • Why can't you just use `sed` or [fart](http://sourceforge.net/projects/fart-it/) to remove the `foo/`s from the includes? – Avi Ginsburg Apr 19 '15 at 06:20

3 Answers3

4

There is no option which tells gcc to ignore directory prefixes in include paths. If your program contains #include <foo/header.h>, there must be some path_prefix in the include list such that path_prefix/foo/header.h resolves to the desired file.

While you cannot configure gcc to ignore the foo, you can certainly modify the filesystem as you please. All you need is that there be somewhere a directory foo which maps onto the directory where the header files are stored. Then you can add the parent of that directory to the search path.

For example:

mkdir /tmp/fake
ln -s /path/to/directory/containing/header /tmp/fake/foo
gcc -I /tmp/fake ...             # Ta-daa!
rici
  • 234,347
  • 28
  • 237
  • 341
  • Thanks @rici. I tried this, and it broke GDB debugging. GDB can't find symbols to set breakpoints on the class member I am trying to modify. Later, I need to generate a unified diff after performing a `svn add`. This is really inconvenient :( – jww Apr 19 '15 at 05:33
  • @jww: The easiest way is undoubtedly to duplicate your directory structure. All the same, I don't see why gdb wouldn't be able to find the symbols, as long as the symlink still exists. (Using /tmp might not be the best way of guaranteeing that :) ) Are you sure the class member is present in the compiled code? – rici Apr 19 '15 at 07:10
1

Using the -I option to add the current folder as an include directory, you could create a folder called "foo" in the current directory and put your libfoo.h file inside.

Obviously, this doesn't strip the "foo" prefix in your #include, but it is a workaround.

Corb3nik
  • 1,177
  • 7
  • 26
  • Thanks @Cubia. Some of the back story is I need to generate an `svn diff` of the changes with the test files. Essentially, I will do an `svn add` on the test files. Changing the directory structure complicates things. – jww Apr 19 '15 at 03:02
1

I have about 60 extra test files I use for the library. And each has 10 or 20 includes like this. So I can't go through and change #include to #include "./libfoo.h" in 500 or 600 places.

If the above criteria is just a matter of convenience, then a tool like sed can be used to do all the work. Something like

$ sed -i 's/\(^\s*#include\s*[<"]\)foo\/\([^>"]*[>"]\s*$\)/\1\2\t\/\/ This line was replaced/' *

will replace all the occurrences of #include <foo/file.h> with #include <file.h> (you might have to adjust it slightly, I'm on a Windows machine at the moment and can't test it). This will work if all the files are in the PWD. If there is a more complex file structure, then it can be used in conjunction with grep and xargs.

NOTE: Make sure that the svn directories are ignored when using.

Avi Ginsburg
  • 10,323
  • 3
  • 29
  • 56