[CMake] several questions about cmake

Mark Roden mmroden at gmail.com
Thu Aug 26 11:38:51 EDT 2010


On Wed, Aug 25, 2010 at 11:17 PM, Michael Wild <themiwi at gmail.com> wrote:
>
> On 26. Aug, 2010, at 1:34 , Mark Roden wrote:
>
>> I'm starting to get deep into CMake, and I have a few questions as I
>> try to convert the socket++ library such that it can be compiled by
>> CMake on Windows.
>>
>
> Cool!
Thanks, I think so to :)

>
>> 1) The default install directory on Windows is C:\Program Files, or
>> C:\Program Files (x86) on 64 bit.  This default will not work on
>> Windows 7 (and perhaps Vista), because the user isn't running as
>> administrator anymore, and only administrators can modify that
>> directory.  There should probably be a warning to that effect on
>> windows systems; otherwise, there are painful ways to run install, but
>> they are painful.
>
> I hope you will create an installer using CPack, and most users will then use that instead of compiling from sources, so IMHO that is no real problem.

I generally intend to create an installer using WiX, mainly out of
ignorance of CPack and extensive experience using WiX.  Not that WiX
is better-- it has some serious usability problems-- but it integrates
nicely with visual studio.

However, I'm more talking about when I run CMake to install on my own machine.

My work paradigm runs like this:
1) get all the libraries I need
2) compile them all
3) put the libraries and headers into a file
4) make my own project in visual studio
5) reference those libraries and headers in my project

Why not put it all into CMake, I hear you cry?  A few reasons:
1) For the longest time (and still ongoing), the gdcm version in itk
doesn't match the latest greatest from gdcm.  There is a compiler
switch to use 'system gdcm', whatever that means on Windows, but other
projects I have require the 1.2 branch in itk.  So I can (and do) have
multiple versions of itk to account for this, and so need to ensure I
reference the right one.
2) I'm generally not messing directly with the libraries I install via
cmake, I just compile against them and use provided functions.  Going
through the cmakelists process is not helpful when I'm just using the
libraries as is.  When I modify the libraries, then I use CMake,
because that's the way these libraries come.
3) Since I don't want to recompile the libraries on multiple machines,
I just check in the results of running the installation into source
control.  This works great when you're deploying on windows;
everything compiles and builds on one machine will work on another, so
reproducing my dev environment, either for a coworker or for myself on
another machine, is much simpler and saves more time than getting the
source, making sure it's the same source as what I started with, and
rebuilding again.

So, yes, a warning would be very nice, given the way that I use the
installation option in CMake.
>
>>
>> 2) I'm trying to check to see if a certain C++ code chunk will
>> compile.  The line is:
>>
>> CHECK_CXX_SOURCE_COMPILES("
>> #include <string.h>
>> #include <stdio.h>
>> void main(){
>>  char buf[100];
>>  char buf2[100];
>>  strncpy(buf2, buf, 5);
>>  buf2[5] = '\0';
>>  puts(buf2);
>> }" EXTERN_C)
>>
>> The EXTERN_C test is failing here.  The problem is, I can cut and
>> paste that code into a blank project in vs2008 and it compiles just
>> fine.  Is there a way to see the compiler error, or to determine why
>> that would fail?
>>
>> The code in the configure.in file is:
>>
>> AC_TRY_LINK([
>> # include <string.h>
>> # include <stdio.h>
>> ], [
>>  char buf[100];
>>  strcpy(buf, "Hello world\n");
>> ],
>>  bz_cv_cplusplus_needexternCwrapper=no,
>>  bz_cv_cplusplus_needexternCwrapper=yes)
>> ])
>>
>> I can't use that directly (or can I?) because the quotation marks in
>> "Hello World" prematurely cut off the code in the SOURCE section of
>> CHECK_CXX_SOURCE_COMPILES, and I get an error that the variable World"
>> makes no sense.
>
> Just put \ in front of the quotation marks, and the hello world code will work.

That's not my point.  The code I gave has no double quotes in it, and
it still doesn't compile properly, but it does compile and work in a
visual studio environment.
If I do:

CHECK_CXX_SOURCE_COMPILES("
#include <string.h>
#include <stdio.h>
 void main(){
  char buf[100];
  strcpy(buf, \"Hello world\n\");
 }" EXTERN_C)

I get

Performing Test EXTERN_C
Performing Test EXTERN_C - Failed

But that code compiles in an empty vs2008 project.

 How can I get the compiler error?  I don't see why this code test should fail.

>
>
>>
>> 3) There is a check for the presence of the Libg++ library, but no
>> specific mention of which function is needed.  According to what I can
>> find on CheckLibraryExists, I need to provide a specific function to
>> determine if that library is present.  The code in configure.in is:
>>
>> AC_CHECK_HEADER(_G_config.h, AC_DEFINE(_S_LIBGXX))
>>
>> In that case, should I be looking for a particular function in
>> _G_config.h (which I don't have, since I'm on Windows) and just using
>> it arbitrarily?  I'm not even close to the point where this code can
>> fail in compilation and therefore determine the error directly.
>
> In that case I just find a sufficiently unique function in libg++ (using e.g. the nm tool on Unix systems or dumpbin on Windows). But what above code actually does corresponds to
>
> find_file(G_CONFIG_H_PATH _G_config.h)
> if(G_CONFIG_H_PATH)
>  set(_S_LIBGXX 1)
> else()
>  set(_S_LIBGXX 0)
> endif()
>
> Actually, it does a bit more (see the docs of AC_DEFINE), but I don't think it is relevant to you.

Thanks, I'll add that in!

I'm assuming that it works, because when I swap around the 1 and the
0, I get the opposite result (ie, it things that _S_LIBGXX should be
1).

>
>>
>> 4) There are two checks for potentially predefined variables, namely
>> sys_siglist and sys_errlist.  The code to check for these looks like:
>>
>> AC_CACHE_VAL(socketxx_cv_siglist, [
>> AC_TRY_LINK([
>> # include <unistd.h>
>> # include <sys/signal.h>
>> ], [
>> #ifndef _sys_siglist
>>  extern char* _sys_siglist[];
>> #endif
>>  puts(*_sys_siglist);
>> ],
>> socketxx_cv_siglist=_sys_siglist,
>> socketxx_cv_siglist=sys_siglist) ])
>> AC_DEFINE_UNQUOTED(SYS_SIGLIST, $socketxx_cv_siglist)
>>
>> Windows doesn't have unistd.h or sys/signal.h, so I know that this
>> will fail, regardless of the test.  I'm unfamiliar with these
>> variables; does anyone have any insight into them?  It looks like if
>> the code compiles, the variable _sys_siglist will be used, otherwise,
>> sys_siglist, whatever that is.  I'm tempted to just say that it is
>> what it is, and if other unix users have issues, we can fix the cmake
>> file then.  The typical sloppiness of someone not dealing with their
>> native platform, I guess :)
>>
>
> Those are definitely unixy, they contain operating system signal and error descriptions and are usually accessed through the psginal, strsignal, perror and strerror family of functions. Normally they should not be accessed directly. I think the above code assumes it's running on Unix and just determines whether the C library implementor prefixed the variables with a _ (to mark them for internal use only).

Right, ok.

This code does need to work with linux, as it's going to be deployed
via cmake.  Should I just get a colleague using linux to fix those up
then?  How would they go about checking which version to use?

Thanks much!
Mark


More information about the CMake mailing list