On 12/22/2010 07:49 PM, Pere Mato Vila wrote: > AFAICS there are three different issues here: > > - Having a .def file as a source in a ADD_LIBRARY() it does the correct > thing, which is using it to build the library, but it does not create a > dependency to it. I would call this a bug.
For the nmake generator, this was asked in [1] two years ago but hasn't received an answer; nevertheless, it seems to have been fixed recently in [2]. However, I have no idea if it will work with the Visual Studio generators and, as the case may be, why not. Perhaps due to the same reason the upcoming LINK_DEPENDS property is limited to Makefiles? > - The way to generate the .def file that I have figured out is perhaps not > optimal and Bill Hoffman has provided me with a solution that exploits > PRE_LINK option in ADD_CUSTOM_COMMAND(). If I understand correctly, you need a dependency of ${library}.def on ${library}-static, and such a dependency can't be established by the ADD_CUSTOM_COMMAND(TARGET ...) signature. In other words: A changed ${library}-static doesn't invalidate ${library}.def, so ${library} isn't rebuilt despite the new dependency on .def files. See the following example with an object file instead of a .def file: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(OBJECT C) FILE(WRITE ${CMAKE_BINARY_DIR}/f.c "void f(void){}\n") FILE(WRITE ${CMAKE_BINARY_DIR}/f0.c "void f0(void){}\n") EXECUTE_PROCESS(COMMAND cc -c f0.c) ADD_LIBRARY(f SHARED f.c f0.o) ADD_CUSTOM_COMMAND(TARGET f PRE_LINK COMMAND cc -c f0.c) f0.o is compiled right before the library target is linked, but touching f0.c - the prerequisite of f0.o - will entail nothing. > - If I use ADD_LBRARY() with no real source files and only with a .def file > does fail within the IDE (Visual Studio 9) and does work with nmake. Just a spontaneous notion: On *nix, one can say ADD_LIBRARY(f SHARED "" f.def) # Note the "". SET_TARGET_PROPERTIES(f PROPERTIES LINKER_LANGUAGE C) In spite of f.def not being compilable such that there's no mediate f.def <-- f dependency - that is what I actually meant with "CMake does not know how to handle a .def file" - the target gets happily built without object files, but I don't know if the Visual Studio tools can be duped in this way. Regards, Michael [1] http://www.mail-archive.com/cmake@cmake.org/msg17981.html [2] http://public.kitware.com/Bug/view.php?id=11014 > On Dec 22, 2010, at 12:09 AM, Michael Hertling wrote: > >> 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 _______________________________________________ Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://www.cmake.org/mailman/listinfo/cmake