[CMake] Reusing an already built object
Linghua Tseng
uranus at tinlans.org
Fri Jun 11 22:10:44 EDT 2010
Continue the lastest post of this article:
http://www.cmake.org/pipermail/cmake/2009-October/032615.html
> On Tuesday 13 October 2009, Alexander Neundorf wrote:
> > On Tuesday 13 October 2009, Naram Qashat wrote:
> > Say I have a main executable and a number of shared libraries that rely on
> > that executable. Say I have a certain C++ source that is required to be
> > built by not only the main executable, but also every single shared library
> > (the source in question is a Windows-specific file to handle memory
> > allocations). I have found that when using a Visual Studio generator,
> > CMake causes the source file to be rebuilt for every single shared library,
> > causing an increase in build time. Is there an easy way to have the object
> > file not be rebuilt every single time, but be reused for all the shared
> > libraries?
>
> No, it's a feature.
> You may use different compile flags etc. for your different targets, so you
> may get different object files.
>
> You may hack around that by creating a static library, figuring out the path
> to the object files and then link these object files directly to your targets
> (or something like that, but I've never done that and I don't recommend it).
Consider the following scenario:
gcc -c src1.c
gcc gen_src2.c -o gen_src2 src1.o
./gen_src2 > src2.c
gcc -c src2.c
gcc gen_src3.c -o gen_src3 src1.o src2.o
./gen_src3 > src3.c
gcc -c src3.c
gcc gen_src4.c -o gen_src4 src1.o src2.o src3.o
./gen_src4 > src4.c
...
gcc -c src99.c
gcc gen_src100.c -o gen_src100 src1.o src2.o src3.o ... src99.o
./gen_src100 > src100.c
gcc -c src100.c
ar rcu libmylib.a src1.o src2.o src3.o ... src100.o
To create a project by using CMake,
we'll have several targets by using add_executable():
gen_src2, gen_src3, gen_src4, ... gen_src100
And we'll have a target by using add_library():
mylib
Assume we already have gen_src1.c, gen_src2.c, ..., gen_src100.c, and src1.c
Without lost of generality, I reduce the example to src1 ~ src4.
Then we have to write the following CMakeLists.txt:
project(main)
cmake_minimum_required(VERSION 2.8)
set(gen_src2_SRCS src1.c gen_src2.c)
add_executable(gen_src2 ${gen_src2_SRCS})
get_target_property(gen_src2_EXE gen_src2 LOCATION)
add_custom_command(
OUTPUT src2.c
COMMAND ${gen_src2_EXE}
ARGS > src2.c
DEPENDS gen_src2
)
set(gen_src3_SRCS src1.c ${PROJECT_BINARY_DIR}/src2.c gen_src3.c)
add_executable(gen_src3 ${gen_src3_SRCS})
get_target_property(gen_src3_EXE gen_src3 LOCATION)
add_custom_command(
OUTPUT src3.c
COMMAND ${gen_src3_EXE}
ARGS > src3.c
DEPENDS gen_src3
)
set(gen_src4_SRCS src1.c ${PROJECT_BINARY_DIR}/src2.c ${PROJECT_BINARY_DIR}/src3.c gen_src4.c)
add_executable(gen_src4 ${gen_src4_SRCS})
get_target_property(gen_src4_EXE gen_src4 LOCATION)
add_custom_command(
OUTPUT src4.c
COMMAND ${gen_src4_EXE}
ARGS > src4.c
DEPENDS gen_src4
)
set(mylib_SRCS src1.c
${PROJECT_BINARY_DIR}/src2.c
${PROJECT_BINARY_DIR}/src3.c
${PROJECT_BINARY_DIR}/src4.c
)
add_library(mylib ${PROJECT_BINARY_DIR}/src4.c)
Now the compile-flow shows:
[ 5%] Building C object CMakeFiles/gen_src2.dir/src1.c.o
[ 10%] Building C object CMakeFiles/gen_src2.dir/gen_src2.c.o
Linking C executable gen_src2
[ 10%] Built target gen_src2
[ 15%] Generating src2.c
[ 21%] Building C object CMakeFiles/gen_src3.dir/src1.c.o
[ 26%] Building C object CMakeFiles/gen_src3.dir/src2.c.o
[ 31%] Building C object CMakeFiles/gen_src3.dir/gen_src3.c.o
Linking C executable gen_src3
[ 31%] Built target gen_src3
[ 36%] Generating src3.c
[ 42%] Building C object CMakeFiles/gen_src4.dir/src1.c.o
[ 47%] Building C object CMakeFiles/gen_src4.dir/src2.c.o
[ 52%] Building C object CMakeFiles/gen_src4.dir/src3.c.o
[ 57%] Building C object CMakeFiles/gen_src4.dir/gen_src4.c.o
Linking C executable gen_src4
[ 63%] Built target gen_src4
[ 68%] Generating src4.c
[ 73%] Building C object CMakeFiles/mylib.dir/src1.c.o
[ 78%] Building C object CMakeFiles/mylib.dir/src2.c.o
[ 84%] Building C object CMakeFiles/mylib.dir/src3.c.o
[ 89%] Building C object CMakeFiles/mylib.dir/src4.c.o
Linking C static library libmylib.a
[100%] Built target mylib
In this case, `src1.c.o' was built 4 times.
If the example is src1~src100, it will need to be compiled 100 times.
It's really unnecessary because I don't want to use different CFLAGS for building them.
I know someone said I can build static libraries for avoiding this,
but it will fall into another issue:
[Cmake] How do I link a static library into a library
http://www.cmake.org/pipermail/cmake/2004-April/004990.html
Therefore, it still cannot solve my problem.
The scenario is simplified from a real application (a compiler's source code).
In order to port that compiler to a new target,
developers need to write some description files and execute generators to produce target-dependent codes.
The software architecture is not designed by me,
so I cannot change it although I know it's really a bad design.
I think this feature is really not suitable for this case.
Wouldn't anyone like to add an option or a command to disable it?
More information about the CMake
mailing list