[CMake] Problem building libraries with no sources with Visual Studio 9 (2008)

Michael Hertling mhertling at online.de
Tue Dec 21 18:09:28 EST 2010


On 12/21/2010 08:45 PM, Bill Hoffman wrote:
> On 12/21/2010 2:17 PM, Michael Hertling wrote:
> 
>> AFAIK, this is because CMake does not know how to handle a .def file
>> for incorporation in the target, i.e. ${library}.def has no LANGUAGE
> 
> Actually, it should...
> 
> 
> Something like this should work:
> (assumes you have a perl script to create a .def file)
> 
> cmake_minimum_required (VERSION 2.6)
> project (myexe)
> 
> set (SOURCES mylib.cxx mylib2.cxx)
> 
> # create a list of all the object files
> string (REGEX REPLACE "\\.cxx" ".obj" OBJECTS "${SOURCES}")
> 
> # create a shared library with the .def file
> add_library (mylib SHARED ${SOURCES}
>    ${CMAKE_CURRENT_BINARY_DIR}/mylib.def
>    )
> # set the .def file as generated
> set_source_files_properties (
>    ${CMAKE_CURRENT_BINARY_DIR}/mylib.def
>    PROPERTIES GENERATED 1
>    )
> 
> # create an executable
> add_executable (myexe myexe.cxx)
> 
> # link the executable to the dll
> target_link_libraries(myexe mylib)
> 
> #convert to windows slashes
> set (OUTDIR
>    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
>    )
> 
> string (REGEX REPLACE "/" "\\\\" OUTDIR ${OUTDIR})
> 
> # create a custom pre link command that runs
> # a perl script to create a .def file using dumpbin
> add_custom_command (
>    TARGET mylib PRE_LINK
>    COMMAND perl
>    ARGS ${CMAKE_CURRENT_SOURCE_DIR}/makedef.pl
>    ${CMAKE_CURRENT_BINARY_DIR}\\mylib.def mylib
>    ${OUTDIR} ${OBJECTS} )

Sorry, I haven't expressed myself precisely. My point is that mentioning
the .def file in the target's sources does not establish a dependency of
the target on the .def file, so the target isn't rebuilt when the .def
file has changed:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(DEFS C)
FILE(WRITE ${CMAKE_BINARY_DIR}/f.c "void f(void){}\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/f.def.in "")
ADD_CUSTOM_COMMAND(
    OUTPUT ${CMAKE_BINARY_DIR}/f1.def
    COMMAND ${CMAKE_COMMAND} -E
    copy ${CMAKE_BINARY_DIR}/f.def.in ${CMAKE_BINARY_DIR}/f1.def
    DEPENDS ${CMAKE_BINARY_DIR}/f.def.in
)
SET_SOURCE_FILES_PROPERTIES(
    ${CMAKE_BINARY_DIR}/f2.def PROPERTIES GENERATED TRUE
)
ADD_LIBRARY(f SHARED f.c f1.def f2.def)
ADD_CUSTOM_COMMAND(
    TARGET f
    PRE_LINK
    COMMAND ${CMAKE_COMMAND} -E copy
    ${CMAKE_BINARY_DIR}/f.def.in ${CMAKE_BINARY_DIR}/f2.def
)

Touching f1.def or f2.def does not make the target rebuild, and touching
f.def.in just makes f1.def regenerate. It's touching f.c that results in
rebuilding the target due to the f.c <-- f.c.o <-- libf.so dependencies.
AFAIK, such a dependency does not exist between the target and the .def
files, or have I got you wrong?

Regards,

Michael


More information about the CMake mailing list