[CMake] How to handle dependencies for custom cmake builder?

Doug douglas.linder at gmail.com
Tue Jun 12 03:44:35 EDT 2012


Hi,

I'm trying to use cmake to build c# files, on a linux box using mono.

I've got it pretty much working, but I can't figure how how to bundle
dependencies between libraries.

Basically, the builder does this:

- Create a fake builder library with the real build command (using gcs)
- Create a fake builder binary that depends on the library
- Use post build to run the builder binary

This is cool, because you can use target_link_library() to link
dependencies between libraries and then they get build in the right order.
(doesn't actually work at the moment; build.c.in needs to have a unique run
command name)

However, I want to generate a list of dependencies to pass into each build
command.

So, if I have a library with 4 dependencies, somehow query, get a list of
those, and then generate the build.c file with the relevant dlls listed in
them.

Is that possible? Can I query the list of dependencies on a target somehow?

The full source is below.

runner.c:
#include <stdio.h>
void run(void);
int main(int argc, char *argv[]) {
  run();
}

build.c.in:
#include <stdio.h>
void run(void) {
  const char *command = "@MONO_BUILD_COMMAND@";
  printf(": %s", command);
  system(command);
}

CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(MONO_TEST)

# Init mono globals
macro(mono_init)
  set(MONO_GCS "/usr/local/bin/mcs")
endmacro()

# Explode a list into "A B C .. "
function(mono_explode TARGET RETURN)
  set(RTN "")
  foreach(ITEM ${TARGET})
    set(RTN "${RTN} ${ITEM}")
  endforeach()
  set(${RETURN} ${RTN} PARENT_SCOPE)
endfunction()

# Creates a target called TARGET
# @param TARGET The name of the target
# @param SOURCE The set of source files
# @param LIB If this is a library
function(add_mono_target TARGET SOURCES LIB)
  set(MONO_BUILD_TARGET "${PROJECT_BINARY_DIR}/builders/${TARGET}/build.c")
  set(MONO_BUILD_PATH "${PROJECT_BINARY_DIR}/builders/${TARGET}/")
  set(MONO_BUILD_RUNNER "${TARGET}_runner")
  set(MONO_BUILD_LIB "${TARGET}")

  file(MAKE_DIRECTORY ${MONO_BUILD_PATH})
  mono_explode("${SOURCES}" MONO_SRC)
  if(${LIB})
    set(MONO_BUILD_COMMAND "${MONO_GCS} ${MONO_SRC} -target:library
-out:${TARGET}.dll")
  else()
    set(MONO_BUILD_COMMAND "${MONO_GCS} ${MONO_SRC} -out:${TARGET}")
  endif()
  configure_file("${PROJECT_SOURCE_DIR}/helpers/build.c.in"
${MONO_BUILD_TARGET})

  add_library(${MONO_BUILD_LIB} ${MONO_BUILD_TARGET})
  add_executable(${MONO_BUILD_RUNNER}
"${PROJECT_SOURCE_DIR}/helpers/runner.c")
  target_link_libraries(${MONO_BUILD_RUNNER} ${MONO_BUILD_LIB})

  get_target_property(MONO_RUNNER ${MONO_BUILD_RUNNER} LOCATION)
  get_filename_component(MONO_RUNNER ${MONO_RUNNER} ABSOLUTE)
  add_custom_command(TARGET ${MONO_BUILD_RUNNER} POST_BUILD COMMAND
${MONO_RUNNER})
  add_custom_command(TARGET ${MONO_BUILD_RUNNER} POST_BUILD COMMAND
${CMAKE_COMMAND} -E remove ${MONO_RUNNER})
endfunction()

# Creates a library called TARGET
# @param TARGET The name of the library
# @param SOURCE The set of source files
function(add_mono_library TARGET SOURCES)
  add_mono_target(${TARGET} "${SOURCES}" 1)
endfunction()

# Creates a binary called TARGET
# @param TARGET The name of the binary
# @param SOURCE The set of source files
function(add_mono_executable TARGET SOURCES)
  add_mono_target(${TARGET} "${SOURCES}" 0)
endfunction()

# init~
mono_init()

file(GLOB_RECURSE SOURCES "${PROJECT_SOURCE_DIR}/sample1/*.cs")
add_mono_library(mono_sample1 "${SOURCES}")

file(GLOB_RECURSE SOURCES "${PROJECT_SOURCE_DIR}/sample2/*.cs")
add_mono_executable(mono_sample2 "${SOURCES}")

Cheers,
Doug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20120612/348b34e4/attachment-0001.htm>


More information about the CMake mailing list