├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── Readme.md ├── cmake ├── Findcargo.cmake ├── Findrustc.cmake ├── Findrustdoc.cmake └── Rust.cmake ├── examples ├── example1.rs └── example2.rs └── src ├── lib.rs └── other.rs /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | notifications: 2 | email: 3 | on_success: never 4 | before_install: 5 | - wget http://static.rust-lang.org/dist/rust-nightly-x86_64-unknown-linux-gnu.tar.gz 6 | - tar xf rust-nightly-x86_64-unknown-linux-gnu.tar.gz 7 | install: 8 | - sudo ./rust-nightly-x86_64-unknown-linux-gnu/install.sh 9 | script: 10 | - mkdir build 11 | - cd build 12 | - cmake .. -DCMAKE_INSTALL_PREFIX=/tmp 13 | - make -j 14 | - make test -j 15 | - make doc -j 16 | - make install 17 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(test NONE) 3 | 4 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") 5 | find_package(rustc) 6 | find_package(rustdoc) 7 | find_package(cargo) 8 | include(Rust) 9 | 10 | cargo_dependency(cargo 11 | PACKAGE_NAMES url 12 | PACKAGE_VERSIONS =0.2.31) 13 | 14 | set(RUSTC_FLAGS -L ${CMAKE_BINARY_DIR}/lib -L ${CMAKE_BINARY_DIR}/cargo/target/debug/deps) 15 | set(RUSTDOC_FLAGS -L ${CMAKE_BINARY_DIR}/lib -L ${CMAKE_BINARY_DIR}/cargo/target/debug/deps) 16 | 17 | # Get the dependencies of all the crates 18 | get_rust_deps(src/lib.rs TESTLIB_DEPS) 19 | get_rust_deps(examples/example1.rs EXAMPLE1_DEPS) 20 | get_rust_deps(examples/example2.rs EXAMPLE2_DEPS) 21 | 22 | # Build the library 23 | rust_crate(src/lib.rs 24 | ALL 25 | TARGET_NAME TESTLIB 26 | DESTINATION lib 27 | DEPENDS "${TESTLIB_DEPS}" 28 | OTHER_RUSTC_FLAGS --crate-type dylib --crate-type rlib) 29 | 30 | add_custom_target(library_target 31 | ALL 32 | DEPENDS ${TESTLIB_FULL_TARGET}) 33 | 34 | # Build examples 35 | rust_crate(examples/example1.rs 36 | ALL 37 | TARGET_NAME EXAMPLE1 38 | DESTINATION examples 39 | DEPENDS "${TESTLIB_FULL_TARGET};${EXAMPLE1_DEPS}") 40 | rust_crate(examples/example2.rs 41 | ALL 42 | TARGET_NAME EXAMPLE2 43 | DESTINATION examples 44 | DEPENDS "${TESTLIB_FULL_TARGET};${EXAMPLE2_DEPS}") 45 | 46 | # Build tests 47 | rust_crate(examples/example1.rs 48 | TARGET_NAME EXAMPLE1_TEST 49 | DESTINATION test 50 | DEPENDS "${TESTLIB_FULL_TARGET};${EXAMPLE1_DEPS}" 51 | OTHER_RUSTC_FLAGS --test) 52 | rust_crate(examples/example2.rs 53 | TARGET_NAME EXAMPLE2_TEST 54 | DESTINATION test 55 | DEPENDS "${TESTLIB_FULL_TARGET};${EXAMPLE2_DEPS}" 56 | OTHER_RUSTC_FLAGS --test) 57 | 58 | add_custom_target(test 59 | COMMAND ./example1 || true 60 | COMMAND ./example2 || true 61 | WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/test" 62 | DEPENDS ${EXAMPLE1_TEST_FULL_TARGET} ${EXAMPLE2_TEST_FULL_TARGET}) 63 | 64 | 65 | # Build documentation 66 | rust_doc(src/lib.rs 67 | TARGET_NAME TESTLIB_DOC 68 | DESTINATION doc 69 | DEPENDS "${TESTLIB_DEPS}") 70 | rust_doc(examples/example1.rs 71 | TARGET_NAME EXAMPLE1_DOC 72 | DESTINATION doc 73 | DEPENDS "${TESTLIB_FULL_TARGET};${EXAMPLE1_DEPS}") 74 | rust_doc(examples/example2.rs 75 | TARGET_NAME EXAMPLE2_DOC 76 | DESTINATION doc 77 | DEPENDS "${TESTLIB_FULL_TARGET};${EXAMPLE2_DEPS}") 78 | 79 | add_custom_target(doc 80 | DEPENDS ${TESTLIB_DOC_FULL_TARGET} ${EXAMPLE1_DOC_FULL_TARGET} ${EXAMPLE2_DOC_FULL_TARGET}) 81 | 82 | # Install library 83 | install(FILES ${TESTLIB_ARTIFACTS} 84 | DESTINATION lib) 85 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | An example of using CMake with Rust. 2 | 3 | [![Build Status](https://travis-ci.org/SiegeLord/RustCMake.png)](https://travis-ci.org/SiegeLord/RustCMake) 4 | 5 | Try it! 6 | ~~~ 7 | mkdir build 8 | cd build 9 | cmake .. -DCMAKE_INSTALL_PREFIX=/tmp 10 | make -j 11 | make test -j 12 | make doc -j 13 | make install 14 | 15 | cd examples 16 | ./example1 17 | ./example2 18 | ~~~ 19 | 20 | License: 21 | 22 | The example files are released into the public domain, and the CMake modules are licensed under the zlib license (see file contents). 23 | -------------------------------------------------------------------------------- /cmake/Findcargo.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 SiegeLord 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | 22 | find_program(CARGO_EXECUTABLE cargo) 23 | include(FindPackageHandleStandardArgs) 24 | find_package_handle_standard_args(cargo DEFAULT_MSG CARGO_EXECUTABLE) 25 | mark_as_advanced(CARGO_EXECUTABLE) 26 | -------------------------------------------------------------------------------- /cmake/Findrustc.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 SiegeLord 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | 22 | find_program(RUSTC_EXECUTABLE rustc) 23 | include(FindPackageHandleStandardArgs) 24 | find_package_handle_standard_args(rustc DEFAULT_MSG RUSTC_EXECUTABLE) 25 | mark_as_advanced(RUSTC_EXECUTABLE) 26 | 27 | execute_process(COMMAND ${RUSTC_EXECUTABLE} -Vv 28 | OUTPUT_VARIABLE RUSTC_TARGET_TRIPLE 29 | OUTPUT_STRIP_TRAILING_WHITESPACE) 30 | string(REGEX MATCH "host:[ \t](.*)\n" RUSTC_TARGET_TRIPLE "${RUSTC_TARGET_TRIPLE}") 31 | string(REGEX REPLACE "host:[ \t](.*)\n" "\\1" RUSTC_TARGET_TRIPLE "${RUSTC_TARGET_TRIPLE}") 32 | set(RUSTC_TARGET_TRIPLE "${RUSTC_TARGET_TRIPLE}" CACHE STRING "Target triple you can pass to rustc (not passed by default)") 33 | mark_as_advanced(RUSTC_TARGET_TRIPLE) 34 | -------------------------------------------------------------------------------- /cmake/Findrustdoc.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 SiegeLord 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | 22 | find_program(RUSTDOC_EXECUTABLE rustdoc) 23 | include(FindPackageHandleStandardArgs) 24 | find_package_handle_standard_args(rustdoc DEFAULT_MSG RUSTDOC_EXECUTABLE) 25 | mark_as_advanced(RUSTDOC_EXECUTABLE) 26 | -------------------------------------------------------------------------------- /cmake/Rust.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 SiegeLord 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not be 17 | # misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source 20 | # distribution. 21 | 22 | # Defines a few macros, variables and a function to help with compiling Rust 23 | # programs/libraries and documentation with CMake. 24 | # 25 | # This file utilizes several global variables: 26 | # 27 | # RUSTC_EXECUTABLE - Filename of the rustc executable. You can fill it in using the Findrustc package. 28 | # RUSTDOC_EXECUTABLE - Filename of the rustc executable. You can fill it in using the Findrustdoc package. 29 | # RUSTC_FLAGS - These get passed to rustc. 30 | # RUSTDOC_FLAGS - These flags get passed to rustdoc. 31 | 32 | include(CMakeParseArguments) 33 | 34 | if(NOT RUSTC_FLAGS) 35 | set(RUSTC_FLAGS "" CACHE STRING "Flags to pass to the Rust compiler.") 36 | endif() 37 | mark_as_advanced(RUSTC_FLAGS) 38 | 39 | if(NOT RUSTDOC_FLAGS) 40 | set(RUSTDOC_FLAGS "" CACHE STRING "Flags to pass to Rustdoc.") 41 | endif() 42 | mark_as_advanced(RUSTDOC_FLAGS) 43 | 44 | # Fetches the dependencies of a Rust crate with local crate root located at 45 | # local_root_file and places them into out_var. Optionally also builds the crate. 46 | # 47 | # Optional arguments: 48 | # OTHER_RUSTC_FLAGS flags - Other flags to pass to rustc. 49 | # DESTINATION destination - If compiling, where to place the compilation artifacts. 50 | # COMPILE - Whether or not to produce artifacts (it won't by default). 51 | # NOTE! This will force the compillation of this crate every time the 52 | # project is reconfigured, so use with care! 53 | # 54 | # NOTE: Only the first target's dependencies are fetched! 55 | function(get_rust_deps local_root_file out_var) 56 | cmake_parse_arguments("OPT" "COMPILE" "DESTINATION" "OTHER_RUSTC_FLAGS" ${ARGN}) 57 | 58 | set(root_file "${CMAKE_CURRENT_SOURCE_DIR}/${local_root_file}") 59 | 60 | set(dep_dir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/.cmake_rust_dependencies") 61 | file(MAKE_DIRECTORY "${dep_dir}") 62 | 63 | if(OPT_COMPILE) 64 | file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${OPT_DESTINATION}") 65 | set(flags --out-dir "${CMAKE_CURRENT_BINARY_DIR}/${OPT_DESTINATION}") 66 | message(STATUS "Compiling Rust dependency info for crate root ${local_root_file}") 67 | # XXX: It'd be nice if this wasn't a separate operation (need to handle the dep file location being different, or rewrite this macro thing) 68 | execute_process(COMMAND ${RUSTC_EXECUTABLE} ${RUSTC_FLAGS} ${OPT_OTHER_RUSTC_FLAGS} ${flags} "${root_file}") 69 | endif() 70 | 71 | set(flags "-Zno-analysis") 72 | message(STATUS "Getting Rust dependency info for crate root ${local_root_file}") 73 | 74 | execute_process(COMMAND ${RUSTC_EXECUTABLE} ${RUSTC_FLAGS} ${OPT_OTHER_RUSTC_FLAGS} ${flags} --emit dep-info -o "${dep_dir}/deps.d" "${root_file}") 75 | 76 | # Read and parse the dependency information 77 | file(STRINGS "${dep_dir}/deps.d" crate_deps LIMIT_COUNT 1) 78 | file(REMOVE "${dep_dir}/deps.d") 79 | string(REGEX REPLACE ".*: (.*)" "\\1" crate_deps "${crate_deps}") 80 | string(STRIP "${crate_deps}" crate_deps) 81 | string(REPLACE " " ";" crate_deps "${crate_deps}") 82 | 83 | # Make the dependencies be relative to the source directory 84 | set(crate_deps_relative "") 85 | foreach(var IN ITEMS ${crate_deps}) 86 | file(TO_CMAKE_PATH "${var}" var) 87 | file(RELATIVE_PATH var "${CMAKE_CURRENT_SOURCE_DIR}" "${var}") 88 | list(APPEND crate_deps_relative "${var}") 89 | # Hack to re-run CMake if the file changes 90 | configure_file("${var}" "${dep_dir}/${var}" COPYONLY) 91 | endforeach() 92 | 93 | set(${out_var} "${crate_deps_relative}" PARENT_SCOPE) 94 | endfunction() 95 | 96 | # Adds a target to build a rust crate with the crate root located at local_root_file. 97 | # The compilation output is placed inside DESTINATION within the build directory. 98 | # 99 | # Please pass the crate dependencies obtained through get_rust_deps to the dependencies argument in 100 | # addition to other targets/files you want this target to depend on. 101 | # 102 | # Optional arguments: 103 | # 104 | # ALL - Pass this to make this crate be built by default. 105 | # DESTINATION dest - Where to place the compilation artifacts. 106 | # TARGET_NAME target - Target name for the command to build this crate. 107 | # DEPENDS depends - List of dependencies of this crate. 108 | # OTHER_RUSTC_FLAGS flags - Other flags to pass to rustc. 109 | # 110 | # This function sets two variables: 111 | # 112 | # ${target_name}_FULL_TARGET - This is what you would use as a set of dependencies 113 | # for other targets when you want them to depend on the 114 | # output of this target. 115 | # 116 | # ${target_name}_ARTIFACTS - The actual files generated by this command. 117 | # You'd use this as a set of files to install/copy elsewhere. 118 | function(rust_crate local_root_file) 119 | cmake_parse_arguments("OPT" "ALL" "DESTINATION;TARGET_NAME" "DEPENDS;OTHER_RUSTC_FLAGS" ${ARGN}) 120 | 121 | if(NOT OPT_TARGET_NAME) 122 | set(OPT_TARGET_NAME CRATE) 123 | endif() 124 | 125 | if(OPT_ALL) 126 | set(ALL_ARG "ALL") 127 | else() 128 | set(ALL_ARG "") 129 | endif() 130 | 131 | set(root_file "${CMAKE_CURRENT_SOURCE_DIR}/${local_root_file}") 132 | 133 | execute_process(COMMAND ${RUSTC_EXECUTABLE} ${RUSTC_FLAGS} ${OPT_OTHER_RUSTC_FLAGS} --print file-names "${root_file}" 134 | OUTPUT_VARIABLE rel_crate_filenames 135 | OUTPUT_STRIP_TRAILING_WHITESPACE) 136 | 137 | # Split up the names into a list 138 | string(REGEX MATCHALL "[^\n\r]+" rel_crate_filenames "${rel_crate_filenames}") 139 | 140 | set(comment "Building ") 141 | set(crate_filenames "") 142 | set(first TRUE) 143 | foreach(name IN ITEMS ${rel_crate_filenames}) 144 | if(${first}) 145 | set(first FALSE) 146 | else() 147 | set(comment "${comment}, ") 148 | endif() 149 | set(comment "${comment}${OPT_DESTINATION}/${name}") 150 | list(APPEND crate_filenames "${CMAKE_CURRENT_BINARY_DIR}/${OPT_DESTINATION}/${name}") 151 | endforeach() 152 | file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${OPT_DESTINATION}") 153 | 154 | add_custom_command(OUTPUT ${crate_filenames} 155 | COMMAND ${RUSTC_EXECUTABLE} ${RUSTC_FLAGS} ${OPT_OTHER_RUSTC_FLAGS} --out-dir "${CMAKE_CURRENT_BINARY_DIR}/${OPT_DESTINATION}" "${root_file}" 156 | DEPENDS ${crate_deps_list} 157 | DEPENDS ${OPT_DEPENDS} 158 | COMMENT "${comment}") 159 | 160 | add_custom_target("${OPT_TARGET_NAME}" 161 | ${ALL_ARG} 162 | DEPENDS ${crate_filenames}) 163 | 164 | set("${OPT_TARGET_NAME}_ARTIFACTS" "${crate_filenames}" PARENT_SCOPE) 165 | # CMake Bug #10082 166 | set("${OPT_TARGET_NAME}_FULL_TARGET" "${OPT_TARGET_NAME};${crate_filenames}" PARENT_SCOPE) 167 | endfunction() 168 | 169 | # Like rust_crate, but fetches the crate dependencies for you. This is convenient 170 | # but inefficient if you want to compile the crate several times with different 171 | # configurations (e.g. with --test and without) or if you want to build documentation. 172 | # 173 | # Optional arguments: 174 | # 175 | # ALL - Pass this to make this crate be built by default. 176 | # DESTINATION dest - Where to place the compilation artifacts. 177 | # TARGET_NAME target - Target name for the command to build this crate. 178 | # DEPENDS depends - List of dependencies of this crate. 179 | # OTHER_RUSTC_FLAGS flags - Other flags to pass to rustc. 180 | # 181 | # This function sets two variables: 182 | # 183 | # ${target_name}_FULL_TARGET - This is what you would use as a set of dependencies 184 | # for other targets when you want them to depend on the 185 | # output of this target. 186 | # 187 | # ${target_name}_ARTIFACTS - The actual files generated by this command. 188 | # You'd use this as a set of files to install/copy elsewhere. 189 | function(rust_crate_auto local_root_file) 190 | cmake_parse_arguments("OPT" "ALL" "DESTINATION;TARGET_NAME" "DEPENDS;OTHER_RUSTC_FLAGS" ${ARGN}) 191 | 192 | if(NOT OPT_TARGET_NAME) 193 | set(OPT_TARGET_NAME CRATE) 194 | endif() 195 | 196 | if(OPT_ALL) 197 | set(ALL_ARG "ALL") 198 | else() 199 | set(ALL_ARG "") 200 | endif() 201 | 202 | get_rust_deps(${local_root_file} crate_deps_list 203 | OTHER_RUSTC_FLAGS ${OPT_OTHER_RUSTC_FLAGS}) 204 | 205 | rust_crate("${local_root_file}" 206 | ${ALL_ARG} 207 | TARGET_NAME "${OPT_TARGET_NAME}" 208 | DESTINATION "${OPT_DESTINATION}" 209 | DEPENDS "${crate_deps_list};${OPT_DEPENDS}" 210 | OTHER_RUSTC_FLAGS ${OPT_OTHER_RUSTC_FLAGS}) 211 | set("${OPT_TARGET_NAME}_ARTIFACTS" "${${OPT_TARGET_NAME}_ARTIFACTS}" PARENT_SCOPE) 212 | set("${OPT_TARGET_NAME}_FULL_TARGET" "${${OPT_TARGET_NAME}_FULL_TARGET}" PARENT_SCOPE) 213 | endfunction(rust_crate_auto) 214 | 215 | # Like rust_crate, but this time it generates documentation using rust_doc. 216 | # 217 | # Optional arguments: 218 | # 219 | # ALL - Pass this to make this crate be built by default. 220 | # DESTINATION dest - Where to place the compilation artifacts. 221 | # TARGET_NAME target - Target name for the command to build this crate. 222 | # DEPENDS depends - List of dependencies of this crate. 223 | # OTHER_RUSTC_FLAGS flags - Other flags to pass to rustc. 224 | # OTHER_RUSTDOC_FLAGS flags - Other flags to pass to rustdoc. 225 | # 226 | # This function sets two variables: 227 | # 228 | # ${target_name}_FULL_TARGET - This is what you would use as a set of dependencies 229 | # for other targets when you want them to depend on the 230 | # output of this target. 231 | # 232 | # ${target_name}_ARTIFACTS - The actual files generated by this command. 233 | # You'd use this as a set of files to install/copy elsewhere. 234 | function(rust_doc local_root_file) 235 | cmake_parse_arguments("OPT" "ALL" "DESTINATION;TARGET_NAME" "DEPENDS;OTHER_RUSTDOC_FLAGS;OTHER_RUSTC_FLAGS" ${ARGN}) 236 | 237 | if(NOT OPT_TARGET_NAME) 238 | set(OPT_TARGET_NAME DOC) 239 | endif() 240 | 241 | if(OPT_ALL) 242 | set(ALL_ARG "ALL") 243 | else() 244 | set(ALL_ARG "") 245 | endif() 246 | 247 | set(root_file "${CMAKE_CURRENT_SOURCE_DIR}/${local_root_file}") 248 | 249 | execute_process(COMMAND ${RUSTC_EXECUTABLE} ${RUSTC_FLAGS} ${OPT_OTHER_RUSTC_FLAGS} --print crate-name "${root_file}" 250 | OUTPUT_VARIABLE crate_name 251 | OUTPUT_STRIP_TRAILING_WHITESPACE) 252 | 253 | set(doc_dir "${CMAKE_CURRENT_BINARY_DIR}/${OPT_DESTINATION}/${crate_name}") 254 | set(src_dir "${CMAKE_CURRENT_BINARY_DIR}/${OPT_DESTINATION}/src/${crate_name}") 255 | file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${OPT_DESTINATION}") 256 | 257 | add_custom_command(OUTPUT "${doc_dir}/index.html" "${doc_dir}" "${src_dir}" 258 | COMMAND ${RUSTDOC_EXECUTABLE} ${RUSTDOC_FLAGS} ${OPT_OTHER_RUSTDOC_FLAGS} -o "${CMAKE_CURRENT_BINARY_DIR}/${OPT_DESTINATION}" "${root_file}" 259 | DEPENDS ${crate_deps_list} 260 | DEPENDS ${OPT_DEPENDS}) 261 | 262 | add_custom_target("${OPT_TARGET_NAME}" 263 | ${ALL_ARG} 264 | DEPENDS "${doc_dir}/index.html") 265 | 266 | set("${OPT_TARGET_NAME}_ARTIFACTS" "${doc_dir};${src_dir}" PARENT_SCOPE) 267 | # CMake Bug #10082 268 | set("${OPT_TARGET_NAME}_FULL_TARGET" "${OPT_TARGET_NAME};${doc_dir}/index.html" PARENT_SCOPE) 269 | endfunction() 270 | 271 | # Like rust_crate_auto, but this time it generates documentation using rust_doc. 272 | # 273 | # Optional arguments: 274 | # 275 | # ALL - Pass this to make this crate be built by default. 276 | # DESTINATION dest - Where to place the compilation artifacts. 277 | # TARGET_NAME target - Target name for the command to build this crate. 278 | # DEPENDS depends - List of dependencies of this crate. 279 | # OTHER_RUSTC_FLAGS flags - Other flags to pass to rustc. 280 | # OTHER_RUSTDOC_FLAGS flags - Other flags to pass to rustdoc. 281 | # 282 | # This function sets two variables: 283 | # 284 | # ${target_name}_FULL_TARGET - This is what you would use as a set of dependencies 285 | # for other targets when you want them to depend on the 286 | # output of this target. 287 | # 288 | # ${target_name}_ARTIFACTS - The actual files generated by this command. 289 | # You'd use this as a set of files to install/copy elsewhere. 290 | function(rust_doc_auto local_root_file) 291 | cmake_parse_arguments("OPT" "ALL" "DESTINATION;TARGET_NAME" "DEPENDS;OTHER_RUSTC_FLAGS;OTHER_RUSTDOC_FLAGS" ${ARGN}) 292 | 293 | if(NOT OPT_TARGET_NAME) 294 | set(OPT_TARGET_NAME DOC) 295 | endif() 296 | 297 | if(OPT_ALL) 298 | set(ALL_ARG "ALL") 299 | else() 300 | set(ALL_ARG "") 301 | endif() 302 | 303 | get_rust_deps(${local_root_file} crate_deps_list 304 | OTHER_RUSTC_FLAGS ${OPT_OTHER_RUSTC_FLAGS}) 305 | 306 | rust_doc("${local_root_file}" 307 | ${ALL_ARG} 308 | TARGET_NAME "${OPT_TARGET_NAME}" 309 | DESTINATION "${OPT_DESTINATION}" 310 | DEPENDS "${crate_deps_list};${OPT_DEPENDS}" 311 | OTHER_RUSTC_FLAGS ${OPT_OTHER_RUSTC_FLAGS} 312 | OTHER_RUSTDOC_FLAGS ${OPT_OTHER_RUSTDOC_FLAGS}) 313 | set("${OPT_TARGET_NAME}_ARTIFACTS" "${${OPT_TARGET_NAME}_ARTIFACTS}" PARENT_SCOPE) 314 | set("${OPT_TARGET_NAME}_FULL_TARGET" "${${OPT_TARGET_NAME}_FULL_TARGET}" PARENT_SCOPE) 315 | endfunction() 316 | 317 | # Creates a dummy cargo project named ${name} to fetch crates.io dependencies. 318 | # The package will be created in the ${CMAKE_CURRENT_BINARY_DIR}. Typically you 319 | # would then pass "-L ${CMAKE_CURRENT_BINARY_DIR}/target/debug/deps" to rustc so 320 | # it can pick up the dependencies. 321 | # 322 | # Optional arguments: 323 | # 324 | # OTHER_CARGO_FLAGS - Flags to pass to cargo. 325 | # PACKAGE_NAMES - List of package names to fetch. 326 | # PACKAGE_VERSIONS - List of package versions to fetch. 327 | function(cargo_dependency name) 328 | cmake_parse_arguments("OPT" "" "" "OTHER_CARGO_FLAGS;PACKAGE_NAMES;PACKAGE_VERSIONS" ${ARGN}) 329 | 330 | list(LENGTH OPT_PACKAGE_NAMES num_packages) 331 | list(LENGTH OPT_PACKAGE_VERSIONS num_versions) 332 | if(NOT ${num_packages} EQUAL ${num_versions}) 333 | message(FATAL_ERROR "Number of cargo packages doesn't match the number of cargo versions.") 334 | endif() 335 | 336 | set(cargo_dependency_dir "${CMAKE_CURRENT_BINARY_DIR}/${name}") 337 | file(MAKE_DIRECTORY "${cargo_dependency_dir}") 338 | file(MAKE_DIRECTORY "${cargo_dependency_dir}/src") 339 | 340 | set(CARGO_TOML [package] \n name = \"cargo_deps_fetcher\" \n version = \"0.0.0\" \n authors = [\"none\"] \n) 341 | 342 | math(EXPR num_packages "${num_packages} - 1") 343 | foreach(pkg_idx RANGE 0 ${num_packages}) 344 | list(GET OPT_PACKAGE_NAMES ${pkg_idx} pkg_name) 345 | list(GET OPT_PACKAGE_VERSIONS ${pkg_idx} pkg_version) 346 | set(CARGO_TOML ${CARGO_TOML} \n [dependencies.${pkg_name}] \n version = \"${pkg_version}\" \n) 347 | endforeach() 348 | 349 | file(WRITE "${cargo_dependency_dir}/Cargo.toml" ${CARGO_TOML}) 350 | file(WRITE "${cargo_dependency_dir}/src/lib.rs" "") 351 | 352 | execute_process(COMMAND ${CARGO_EXECUTABLE} build ${CARGO_FLAGS} ${OPT_OTHER_CARGO_FLAGS} 353 | WORKING_DIRECTORY ${cargo_dependency_dir}) 354 | endfunction() 355 | -------------------------------------------------------------------------------- /examples/example1.rs: -------------------------------------------------------------------------------- 1 | extern crate cmake_test; 2 | 3 | /// This is a function inside the example 1. 4 | pub fn example_function() 5 | { 6 | println!("Testing example 1...\n"); 7 | } 8 | 9 | #[test] 10 | fn example_test() 11 | { 12 | example_function(); 13 | } 14 | 15 | #[cfg(not(test))] 16 | fn main() 17 | { 18 | cmake_test::other::test(); 19 | } 20 | -------------------------------------------------------------------------------- /examples/example2.rs: -------------------------------------------------------------------------------- 1 | extern crate cmake_test; 2 | 3 | /// This is a function inside the example 2. 4 | pub fn example_function() 5 | { 6 | println!("Testing example 2...\n"); 7 | } 8 | 9 | #[test] 10 | fn example_test() 11 | { 12 | example_function(); 13 | } 14 | 15 | #[cfg(not(test))] 16 | fn main() 17 | { 18 | cmake_test::other::test(); 19 | } 20 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Test library compiled using CMake. 2 | 3 | #![crate_name="cmake_test"] 4 | #![crate_type="lib"] 5 | 6 | extern crate url; 7 | 8 | pub mod other; 9 | -------------------------------------------------------------------------------- /src/other.rs: -------------------------------------------------------------------------------- 1 | /// Test function 2 | pub fn test() 3 | { 4 | println!("Hello"); 5 | } 6 | --------------------------------------------------------------------------------