SiegeLord / RustCMake

An example project showing usage of CMake with Rust
109 stars 15 forks source link

Project using getopts does not compile #4

Open MathiasMagnus opened 9 years ago

MathiasMagnus commented 9 years ago

Hi!

There is a multilanguage project that cries out for CMake, and Rust is one of them, but I would save ourselves from using muliple flavors of make. (Note that I am not the author of the Rust sources, I am just responsible for holding the project together. There are several developers, each responsible for one language.)

There is a manybody-rust-common.rs crate that holds common functionality for all executables, one being parsing arguements using getopts. Then there are multiple executables manybody-rust-v0, v1, v2, etc. that use this common crate.

What is the best way to compile this? In a C/C++ world I would compile manybody-rust-common to a dynamic or static library and link to it. The author of the Rust sources is a Rust newbie and has a hard time answering what Cargo and rustc under the hood are doing (which I do not blame him for, as Rust on Windows is not trivial). He came up with the following Cargo script:

[package]

name = "manybody"
version = "0.0.1"
authors = ["Email here"]

[[bin]]
name = "manybody0"
path = "src/manybody0.rs"

[[bin]]
name = "manybody1"
path = "src/manybody1.rs"

...

[dependencies]
getopts = "*"

This compiles just fine. Trying to build this with CMake, I came up with the following script using the RustCMake module for the common part:

project (manybody-rust-common)

set (Project_Base_Dir ../../manybody/)

set (CMAKE_USE_RELATIVE_PATH "true")

set (Files_SRCS)
set (Files_SRCS ${Project_Base_Dir}/src/comp_phys_common.rs)

set (Files_BUILD ${Files_SRCS})

# Create filters for IDEs
source_group ("Sources" FILES ${Files_SRCS})

# Get the dependencies of all the crates
get_rust_deps(${Files_SRCS} manybody-rust-common_DEPS COMPILE)

# Build the library
rust_crate(${Files_SRCS}
       ALL
       TARGET_NAME ${PROJECT_NAME}
       DESTINATION lib/${CONFIGURATION_NAME})
       DEPENDS "${manybody-rust-common_DEPS}")

And this is the script for the v0 executable:

project (manybody-rust-v0)

set (Project_Base_Dir ../../manybody/)

set (CMAKE_USE_RELATIVE_PATH "true")

set (Files_SRCS)
set (Files_SRCS ${Project_Base_Dir}/src/manybody0.rs)

set (Files_BUILD ${Files_SRCS})

# Create filters for IDEs
source_group ("Sources" FILES ${Files_SRCS})

# Get the dependencies of all the crates
get_rust_deps(${Files_SRCS} manybody-rust-v0_DEPS)

# Build examples
rust_crate(${Files_SRCS}
       ALL
       TARGET_NAME ${PROJECT_NAME}
       DESTINATION bin/${CONFIGURATION_NAME}
       DEPENDS "${manybody-rust-common_FULL_TARGET};${manybody-rust-v0_DEPS}")

However when I try to build my project, this is what I get:

C:/Users/nagy-_000/Git/comp-phys/manybody/rust/cmake/common/../../manybody//src/comp_phys_common.rs:32:37: 32:53 error: use of undeclared type name `getopts::Options`
C:/Users/nagy-_000/Git/comp-phys/manybody/rust/cmake/common/../../manybody//src/comp_phys_common.rs:32 fn print_usage(program: &str, opts: getopts::Options) {
                                                                                                                               ^~~~~~~~~~~~~~~~
C:/Users/nagy-_000/Git/comp-phys/manybody/rust/cmake/common/../../manybody//src/comp_phys_common.rs:42:20: 42:41 error: failed to resolve. Could not find `Options` in `getopts`
C:/Users/nagy-_000/Git/comp-phys/manybody/rust/cmake/common/../../manybody//src/comp_phys_common.rs:42     let mut opts = getopts::Options::new();
                                                                                                                          ^~~~~~~~~~~~~~~~~~~~~
C:/Users/nagy-_000/Git/comp-phys/manybody/rust/cmake/common/../../manybody//src/comp_phys_common.rs:42:20: 42:41 error: unresolved name `getopts::Options::new`
C:/Users/nagy-_000/Git/comp-phys/manybody/rust/cmake/common/../../manybody//src/comp_phys_common.rs:42     let mut opts = getopts::Options::new();
                                                                                                                          ^~~~~~~~~~~~~~~~~~~~~
error: aborting due to 3 previous errors
NMAKE : fatal error U1077: 'C:\Kellekek\Open-Source\Rust\1.0.0-beta\bin\rustc.exe' : return code '0x65'
Stop.
NMAKE : fatal error U1077: '"C:\Kellekek\Microsoft\Visual Studio\14.0\VC\BIN\amd64\nmake.exe"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"C:\Kellekek\Microsoft\Visual Studio\14.0\VC\BIN\amd64\nmake.exe"' : return code '0x2'
Stop.

Rust is a hell of a language with enormous potential, but I detest how strongly the means of compiling and distributing Rust interacts with the language itself. #pragma lib() is the evil counterpart to this in C++. Source code should have nothing to do with how I want to compile an application. Source code should not contain filenames, neither should a build system depend on directory structure or file naming conventions. It seems Rust has taken a direction where it is getting harder and harder to compile Rust without Cargo. Why should I, a package maintainer (so to say) have to learn a whole new make language just because it goes hand-in-hand with a language? Rust is not born into vacuum, and I think the community should focus more on Rust integrating with other tools, such as the VS Add-In, and RustCMake. If not promote, at least mention them on rust-lang.org.

SiegeLord commented 9 years ago

Yes, cargo integration is an important feature. I am looking into it.

SiegeLord commented 9 years ago

I've added a macro to add cargo dependencies. For dependencies which conflict with the built-in dependencies, you actually need to add a hack for now (I'm not sure how to fix it otherwise). See https://github.com/SiegeLord/RustAlgebloat/blob/master/CMakeLists.txt#L23.

MathiasMagnus commented 9 years ago

I'll check it out in the days to come. My priorities temporarily have shifted, but the project will have to build with CMake, so I'll give it a spin shortly.