0

Let me explain the problem. I have a C-code where a search path for additional plugins is included in a C-string. As long as the Program stays in the build directory of cmake the string should include the plugin folder inside the the build directory. For example

char *plugindir = "/home/.../myproject/build/plugins:/usr/share/myproject/plugins"; 

If the program gets installed via make install I want to change this string to

char *plugindir = "/usr/share/myproject/plugins"; 

and recompile/relink the program before it gets installed. How can this behaviour be realized using CMAKE?

M.K. aka Grisu
  • 2,338
  • 5
  • 17
  • 32
  • 2
    Hard compiling the path is evil. Someday, you'll want to move the program to a new directory or a new machine with a different directory structure. Use an initialization file. – DoxyLover Sep 09 '14 at 17:42
  • @DoxyLover: but then how do you find the initialization file? – Chris Dodd Sep 09 '14 at 19:30
  • This answer for finding the directory containing your executable: http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe/1024937. You could also use an environment variable. – DoxyLover Sep 09 '14 at 21:03
  • Using things like determining the own executable name seems to be vary tricky and platform dependent in my opinion. An usually on a Linux/BSD/*nix system you normally do not move a program or a shared library once it is installed. – M.K. aka Grisu Sep 10 '14 at 07:24
  • at some point you'll need hardcoded paths. hardcoded paths are evil. I would suggest to reduce the amount of them as much as possible. ideally to a single configuration file. recompiling on install is possible, but have you considered using cmake header file generators and link two different versions (it's an evil hack though and it'll haunt you in years). – Alexander Oh Sep 10 '14 at 07:33
  • The build path is included using the CONFIGURE_FILE mechanism of cmake because it changes every time. The idea using two different targets one for the build and one for the install I had already in mind, but as you already mentioned it is a dirty hack and so a want to have a good (and of course a nice) workaround. – M.K. aka Grisu Sep 10 '14 at 08:19

1 Answers1

0

There are many solutions, I can tell you about 2:

  1. use a config file so the plugindir is not hardcoded but dynamically taken from a config file. This is the better solution but you can find. This involves the use of some library like this one.

  2. use # directives. This is an easier solution. In the source file you add something like this:

    #ifdef DIST

    char *plugindir = "/usr/share/myproject/plugins";

    #else

    char *plugindir = "/home/.../myproject/build/plugins:/usr/share/myproject/plugins";

    #endif

And you can use the DIST preprocessor variable (in che C code or in the Makefile) to distinguish between development or "installed" code versions.

  • 1. Then there is the problem to hardcode some possible paths of the configuration file, e.g. /etc, /usr/local/etc,... which results in a similar problem as mentioned by myself before. During the development the config file reside somewhere in the build path and while `make install` it needs to be changed. 2. This part is clear, but the question is how to enable CMAKE to realize this behaviour such that the parts of the code which are influenced by defining `DIST` get recompile when I call `make install` – M.K. aka Grisu Sep 10 '14 at 07:30
  • 1. Yes that's why in this case you must take the config file path as a command line parameter too. 2. You will not use it during `make install` but during `make`. You can create a new make target, i.e. call it "dist". It will add DIST variable use to the CFLAGS used in GCC calls. So when you'll issue the `make install` command, you'll install codes with the right path hardcoded in the previous `make dist` phase. – Stefano Falsetto Sep 10 '14 at 08:10
  • The command line parameter is no option for the project where I need it because the above mentioned problem resides in a shared library and it is not possible to provide a library_init... function to the users because this will destroy the API compatibility to the previous version of my project and this is not possible, so I need the hardcoded path. Furthermore I do not use make directly. I use CMAKE as makefile generator and it should work with the help of CMAKE. The resulting workflow for users should be "cmake .; make; make install" and not "cmake .; make ; make something_else_to_install" . – M.K. aka Grisu Sep 10 '14 at 08:25
  • the flow I'm talking about is not "cmake .; make; make somthing_else_to_install" but: "cmake .;make dist; make install". Anyway, if you want something more "cmake-ish" I think you can read this: http://www.cmake.org/cmake/help/cmake_tutorial.html . See the add_custom_command part. It can be useful. – Stefano Falsetto Sep 10 '14 at 08:50
  • Modifying the path using the add_custom command is not a problem, but you can not a and dependency to cmake's install target such that one can modify a piece of code before install. – M.K. aka Grisu Sep 10 '14 at 08:57