[CMake] cmake 2.8.6 On Linux , link error and added headers to ..._EXTERNAL_OBJECTS for executables

Michael Hertling mhertling at online.de
Wed Nov 16 16:11:50 EST 2011


On 11/16/2011 06:05 PM, Bill Hoffman wrote:
> On 11/16/2011 4:43 AM, Michael Hertling wrote:
>> On 11/15/2011 06:04 PM, Bill Hoffman wrote:
>>> On 11/15/2011 11:52 AM, Michael Hertling wrote:
>>>
>>>> Could you boild down this issue to a minimal and self-sufficient example
>>>> - i.e. a project working with 2.6 (quite old) but failing with 2.8 - and
>>>> post it here for further investigation?
>>>>
>>> There was a bug created for this, and the problem found.  The cmake code
>>> was marking the .h file as an object file.  Must have been a bug fix in
>>> CMake that allowed the .h to be treated as an object file.
>>>
>>> See here for information:
>>> http://public.kitware.com/Bug/view.php?id=12575
>>
>> Hi Bill,
>>
>> many thanks for this hint. Perhaps, I might take the opportunity
>> and ask a related question. In [1], I noted that a file declared
>> as EXTERNAL_OBJECT is delivered to the linker only if it has a
>> name extension mentioned in CMAKE_<LANG>_IGNORE_EXTENSIONS, and
>> this variable isn't accessible to the user. IMO, this is wrong;
>> instead, EXTERNAL_OBJECT files should be supplied to the linker
>> regardless of their name extensions, i.e. the relevant blocks
>> within cmMakefileTargetGenerator::WriteTargetBuildRules() from
>> Source/cmMakefileTargetGenerator.cxx should be swapped. That's
>> also what the user expects from the EXTERNAL_OBJECT property's
>> documention, as the limitation to the ignored extensions isn't
>> mentioned. Is there a reason why this restriction is applied?
>>
> 
> If someone explicitly sets a property on a file, then CMake should honor 
> that property.  They should be able to have files that end in .foobar 
> that have object code in them.  It is not quite the same thing as adding 
> something to a source list that needs to be there just so it will show 
> up in an IDE.   The ignore stuff is only directed at the source lists.

That sounds absolutely reasonable, but look at the following example:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(EXTOBJ C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FILE(WRITE ${CMAKE_BINARY_DIR}/f.c "void f(void){}\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/g.c "void g(void){}\n")
EXECUTE_PROCESS(COMMAND gcc -c f.c -o f.fb)
EXECUTE_PROCESS(COMMAND gcc -c g.c -o g.rc)
SET_SOURCE_FILES_PROPERTIES(f.fb PROPERTIES EXTERNAL_OBJECT TRUE)
SET_SOURCE_FILES_PROPERTIES(g.rc PROPERTIES EXTERNAL_OBJECT TRUE)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
ADD_EXECUTABLE(main main.c f.fb g.rc)

f.fb and g.rc are both object files marked as EXTERNAL_OBJECT. While
g.rc appears in the linker command as expected, f.fb does not since
"fb" isn't among the extensions to be ignored, so it's never tested
for an EXTERNAL_OBJECT property. It seems as if the latter can take
effect only for files with ignored extensions, so how can one pass
a file ending in ".foobar", e.g., to the linker command? Of course,
one can use TARGET_LINK_LIBRARIES(), but for this, EXTERNAL_OBJECT
is not necessary. Perhaps, you could once more shed some light on
this issue, or have I completely misunderstood your point?

Regards,

Michael


More information about the CMake mailing list