Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a build script #94

Open
certik opened this issue Jun 8, 2020 · 1 comment
Open

Implement a build script #94

certik opened this issue Jun 8, 2020 · 1 comment
Labels
specification Issue regarding fpm manifest and model

Comments

@certik
Copy link
Member

certik commented Jun 8, 2020

I would do exactly what Cargo does: https://doc.rust-lang.org/cargo/reference/build-scripts.html

Only I would allow the build script to be any of: any binary, cmake, make, Bash script.

Otherwise the following I would do exactly the same:

  • Inputs: environment variables

  • Outputs: the build script prints to stdout with lines starting with fpm:, everything else is ignored. At the beginning, I would support the following, and we can add more later:

    • fpm:fc-link-lib=[KIND=]NAME --- Adds a library to link (doc)
    • fpm:fc-flags=FLAGS --- Passes certain flags to the compiler (doc).

    That should be enough to get us started. One of the environment variables passed to the build script is which Fortran compiler is being used, so the build script would know what compiler parameters to pass back (for example ifort in general might require different flags than gfortran). In the same way, the flags might depend on the platform (macOS vs Linux vs Windows), so one of the input variables can be what platform we run on.

@ivan-pi
Copy link
Member

ivan-pi commented Nov 22, 2020

I was taking a look at this after some related comments in #118 prompted my interest.

In Rust a crate called cc is used to automate the process of building C dependencies. The crate is organized around two structs, Build - used to specify project and compile options, Tool - used to represent the invocation of the C compiler:

pub struct Build {
    include_directories: Vec<PathBuf>,
    definitions: Vec<(String, Option<String>)>,
    objects: Vec<PathBuf>,
    flags: Vec<String>,
    flags_supported: Vec<String>,
    known_flag_support_status: Arc<Mutex<HashMap<String, bool>>>,
    ar_flags: Vec<String>,
    no_default_flags: bool,
    files: Vec<PathBuf>,
    cpp: bool,
    cpp_link_stdlib: Option<Option<String>>,
    cpp_set_stdlib: Option<String>,
    cuda: bool,
    target: Option<String>,
    host: Option<String>,
    out_dir: Option<PathBuf>,
    opt_level: Option<String>,
    debug: Option<bool>,
    force_frame_pointer: Option<bool>,
    env: Vec<(OsString, OsString)>,
    compiler: Option<PathBuf>,
    archiver: Option<PathBuf>,
    cargo_metadata: bool,
    pic: Option<bool>,
    use_plt: Option<bool>,
    static_crt: Option<bool>,
    shared_flag: Option<bool>,
    static_flag: Option<bool>,
    warnings_into_errors: bool,
    warnings: Option<bool>,
    extra_warnings: Option<bool>,
    env_cache: Arc<Mutex<HashMap<String, Option<String>>>>,
    apple_sdk_root_cache: Arc<Mutex<HashMap<String, OsString>>>,
pub struct Tool {
    path: PathBuf,
    cc_wrapper_path: Option<PathBuf>,
    cc_wrapper_args: Vec<OsString>,
    args: Vec<OsString>,
    env: Vec<(OsString, OsString)>,
    family: ToolFamily,
    cuda: bool,
    removed_args: Vec<OsString>,
}

Most of the fields are self-explanatory. A few ideas that came to my mind upon looking into the Rust code:

  • Fortran has the intrinsic subroutine CALL GET_ENVIRONMENT_VARIABLE(NAME[, VALUE, LENGTH, STATUS, TRIM_NAME) which makes it easy to recover the environment variables.
  • For the same family of compilers, the compile flags for Fortran and C will be the same, meaning that the derived type representing the compiler invocation can be re-used for compiling both Fortran and C source files. (The Rust crate is not limited to C code, it can accept any source code that can be passed to a C or C++ compiler. As such, assembly files with extensions .s (gcc/clang) and .asm (MSVC) can also be compiled.)
  • The cc crate even supports a parallel build feature for C and Rust sources by setting up a job server. Within Fortran we could do something similar using co-arrays or OMP tasks (once dependencies like these are allowed). The feature is enabled conditionally, using the following TOML option:
[build-dependencies]
cc = { version = "1.0", features = ["parallel"] }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
specification Issue regarding fpm manifest and model
Projects
None yet
Development

No branches or pull requests

3 participants