[CMake] Sharing objects between executables
Michael Hertling
mhertling at online.de
Tue Oct 4 20:48:41 EDT 2011
On 10/04/2011 10:42 AM, pellegrini wrote:
> Hi all,
>
> I would need your advise about the strategy to adopt when two
> executables share common object files.
Sharing object files among different targets might mean asking for
trouble - possibly quite subtle trouble - since different targets'
object files may need to be compiled with different sets of flags,
defines etc.; in particular, think of -fPIC w.r.t. object files
destined for a static library as well as for a shared one.
> Here is the context. I have a project that consists in a program (e.g.
> console_prog) that was historically a console program
> on top of which a GUI (gui_prog) was built. The gui_prog calling
> directly the console program via an input file generated by the GUI.
>
> As the gui by itself does not mean anything without its console partner,
> I built a CMakeLists.tx file that contains two add_executables:
>
> - add_executable(console_prog console_prog.f90 module1.f90
> module2.f90 module3.f90 ...)
> - add_executable(gui_prog gui_prog.f90 module1.f90 module2.f90)
>
> My problem is that gui_prog uses some routines included in the source
> files of the console program (e.g. module1.f90 module2.f90).
> I would like to avoid a double build of module1.f90, module2.f90
>
> I see two possibilities:
> - building a static libraries out of the common files and linking it
> to both console_prog and gui_prog executables
Unless you have very good reasons to not do so, this is definitely what
you should aim at. Besides, that's the basic idea of object libraries.
> - using the set_source_files_properties command on the objects files
> generated by pfind build with GENERATED option set to true.
>
> Which approach do you think suit the best to my purpose ? If this is the
> second one: is there an easy way to get/specify the list of the
> object files generated during the pfind build ?
You might use a RULE_LAUNCH_COMPILE target property for this purpose:
# CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LOF C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
ADD_EXECUTABLE(main1 main.c)
SET_TARGET_PROPERTIES(main1 PROPERTIES RULE_LAUNCH_COMPILE "sh
${CMAKE_SOURCE_DIR}/lof.sh <OBJECT> ${CMAKE_BINARY_DIR}/\$\$(basename
<SOURCE>).o")
SET_SOURCE_FILES_PROPERTIES(${CMAKE_BINARY_DIR}/main.c.o PROPERTIES
GENERATED TRUE)
ADD_EXECUTABLE(main2 ${CMAKE_BINARY_DIR}/main.c.o)
SET_TARGET_PROPERTIES(main2 PROPERTIES LINKER_LANGUAGE C)
# lof.sh:
ln -s "$1" "$2"; shift 2; exec "$@"
However, this approach is limited to Makefile generators and makes use
of platform-specific tools like basename, so it's usually inadvisable.
Regards,
Michael
More information about the CMake
mailing list