CMake使用说明

来源:互联网 发布:淘宝摄影师兼职 编辑:程序博客网 时间:2024/06/03 21:35
 

How can I add a dependency to a source file which is generated in a subdirectory?

Rules created with ADD_CUSTOM_COMMAND as above have scope only in the directory in which they are specified. If the generated file is needed in another directory, a target-level dependency needs to be added. Create a target in the subdirectory with the custom rule in order to drive it:

 # subdir/CMakeLists.txt ADD_CUSTOM_COMMAND(    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.c    COMMAND ${CMAKE_COMMAND} copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.c ${CMAKE_CURRENT_BINARY_DIR}/foo.c    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.c    ) ADD_CUSTOM_TARGET(generate_foo DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/foo.c)

Now other targets can depend on the target from the subdirectory:

 # CMakeLists.txt ADD_SUBDIRECTORY(subdir) # Create the executable. ADD_EXECUTABLE(generated ${CMAKE_CURRENT_BINARY_DIR}/subdir/foo.c) # Tell CMake the source won't be available until build time. SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/subdir/foo.c PROPERTIES GENERATED 1) # Make sure the source is generated before the executable builds. ADD_DEPENDENCIES(generated generate_foo)

How do I make my shared and static libraries have the same root name, but different suffixes?

Set the OUTPUT_NAME of your shared and static libraries to the same thing.

 ADD_LIBRARY(foo SHARED ${foo_sources}) ADD_LIBRARY(foo-static STATIC ${foo_sources}) # The library target "foo" already has a default OUTPUT_NAME of "foo", so we don't need to change it. # The library target "foo-static" has a default OUTPUT_NAME of "foo-static", so change it. SET_TARGET_PROPERTIES(foo-static PROPERTIES OUTPUT_NAME "foo") # Now the library target "foo-static" will be named "foo.lib" with MS tools. # This conflicts with the "foo.lib" import library corresponding to "foo.dll", # so we add a "lib" prefix (which is default on other platforms anyway): SET_TARGET_PROPERTIES(foo-static PROPERTIES PREFIX "lib")

How can I generate a source file during the build?

The ADD_CUSTOM_COMMAND command lets you generate a source file that you can then include in another target. For example:

 ADD_CUSTOM_COMMAND(   OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.c   COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.c ${CMAKE_CURRENT_BINARY_DIR}/foo.c   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.c   ) ADD_EXECUTABLE(foo foo.c)

This will create an executable by copying bar.c to foo.c and then compiling foo.c to produce foo. CMake allows you to put generated source files in the current source or binary directory, so we were careful to output foo.c to the current binary directory. When we add foo.c to foo, CMake will look in either directory for it. Even if foo.c does not yet exist, CMake is smart enough to notice that a custom command creates it. (For the file named as the OUTPUT, CMake has its GENERATED source file property set to true.)

You can also use ADD_CUSTOM_COMMAND when the generator command is another executable in the same project.

Sometimes, the program doing the generation may generate multiple output files that each need to be part of the build. CMake 2.4 or higher supports having multiple files listed in the OUTPUT section. For example, suppose you had a program that read input.txt and generated three files output1.cpp, output2.h, and output3.cpp, and that those three files needed to be compiled into an executable program. The cmake list file for that would look like this:

 PROJECT(FOO) # make sure cmake addes the binary directory for the project to the include path INCLUDE_DIRECTORIES(${FOO_BINARY_DIR}) # add the executable that will do the generation ADD_EXECUTABLE(my_generator my_generator.cxx) GET_TARGET_PROPERTY(MY_GENERATOR_EXE my_generator LOCATION) # add the custom command that will generate all three files ADD_CUSTOM_COMMAND(   OUTPUT ${FOO_BINARY_DIR}/output1.cpp ${FOO_BINARY_DIR}/output2.h ${FOO_BINARY_DIR}/output3.cpp   COMMAND ${MY_GENERATOR_EXE} ${FOO_BINARY_DIR} ${FOO_SOURCE_DIR}/input.txt   DEPENDS my_generator   MAIN_DEPENDENCY ${FOO_SOURCE_DIR}/input.txt   ) # now create an executable using the generated files ADD_EXECUTABLE(generated                ${FOO_BINARY_DIR}/output1.cpp                ${FOO_BINARY_DIR}/output2.h                ${FOO_BINARY_DIR}/output3.cpp)

CMake 2.4 allows you to generate a header file. Because generated headers often cause unnecessary rebuilds, you should try to avoid them; consider using the CONFIGURE_FILE command to prepare the header at CMake time. If you must generate a header file, use code like this:

 ADD_CUSTOM_COMMAND(   OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.h   COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.h ${CMAKE_CURRENT_BINARY_DIR}/foo.h   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.h   ) ADD_EXECUTABLE(foo foo.c ${CMAKE_CURRENT_BINARY_DIR}/foo.h)

This is like the first example above, except that it generates a header instead of a C file. The header might not exist when the build system scans foo.c's dependencies, so there is no way for CMake to know that this target requires foo.h unless we can tell it that foo.h may exist in the future. We give CMake this knowledge by listing the generated header file in the set of source files for the target. (This requires CMake 2.4. Previous versions of CMake required use of the OBJECT_DEPENDS source file property.)


0 0
原创粉丝点击