fltk_build/
lib.rs

1/*!
2  # fltk-build
3
4
5    Allows creating native C/C++ fltk/cfltk modules to be used from Rust. This is done by exposing the include paths and lib paths from the built fltk-sys crate on your system.
6
7    ## Usage
8    ```toml,ignore
9    [dependencies] # or [dev-dependencies]
10    fltk = "1.2.17" # this won't work with fltk-bundled
11    # You might need fltk-sys and paste if you use fltk's trait macros
12
13    [build-dependencies]
14    fltk-build = "0.1"
15    fltk-sys = "1.2.17"
16    cc = "1" # or cmake = "0.1"
17    ```
18
19    ## Example
20    build.rs (using `cc`):
21    ```rust,ignore
22    use fltk_build::fltk_out_dir;
23
24    fn main() {
25        let fltk_out_dir = fltk_out_dir().unwrap();
26
27        cc::Build::new()
28            .file("src/my_wid.cpp")
29            .cpp(true)
30            .flag_if_supported("-w")
31            .flag_if_supported("-fno-rtti")
32            .include(&fltk_out_dir.join("include"))
33            .compile("my_wid");
34    }
35    ```
36
37    build.rs (using `cmake-rs`):
38    ```rust,ignore
39    use std::env;
40    use std::path::PathBuf;
41    use fltk_build::fltk_out_dir;
42
43    fn main() {
44        let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
45        let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
46        let fltk_out_dir = fltk_out_dir().unwrap();
47
48        cmake::Config::new("src")
49        .define(
50            "CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES",
51            fltk_out_dir.join("include"),
52        )
53        .build();
54
55        println!(
56        "cargo:rustc-link-search=native={}",
57        out_dir.display()
58        );
59        println!("cargo:rustc-link-lib=static=my_wid");
60
61        match target_os.as_str() {
62            "windows" => (), // doesn't need explicit linking to the C++ stdlib
63            "macos" => println!("cargo:rustc-link-lib=c++"),
64            _ => println!("cargo:rustc-link-lib=stdc++"),
65        }
66    }
67    ```
68
69    In your C/C++ files, you can directly access the FLTK and cfltk headers:
70    ```c++,ignore
71    #include <cfl/cfl_window.h>
72    #include <FL/Fl_Window.H>
73    ```
74
75    If you're using CMake, a minimal CMakeLists.txt example:
76    ```cmake
77    cmake_minimum_required(VERSION 3.0)
78    project(wid)
79
80    if (NOT MSVC)
81    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
82    endif()
83
84    add_library(my_wid my_wid.cpp)
85
86    install(TARGETS my_wid DESTINATION ${CMAKE_INSTALL_PREFIX})
87    ```
88
89    Example crate (not published on crates.io) using fltk-build:
90    https://github.com/fltk-rs/fltk-flow
91 */
92use std::env;
93use std::fs;
94use std::path::PathBuf;
95
96pub fn fltk_out_dir() -> Option<PathBuf> {
97    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
98    let build_dir = out_dir.join("../../");
99    for subdir in fs::read_dir(build_dir.clone()).unwrap() {
100        let subdir = subdir
101            .unwrap()
102            .path()
103            .file_name()
104            .unwrap()
105            .to_str()
106            .unwrap()
107            .to_owned();
108        if subdir.contains("fltk-sys") {
109            let temp = build_dir.join(subdir).join("out");
110            if temp.exists() {
111                return Some(temp);
112            }
113        }
114    }
115    None
116}
117
118pub fn link_fltk() {
119    let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
120    let fltk_out_dir = fltk_out_dir().unwrap();
121    println!(
122        "cargo:rustc-link-search=native={}",
123        fltk_out_dir.join("lib").display()
124    );
125
126    for lib in fs::read_dir(fltk_out_dir.join("lib")).unwrap() {
127        let lib = lib
128            .unwrap()
129            .path()
130            .file_stem()
131            .unwrap()
132            .to_str()
133            .unwrap()
134            .to_owned();
135        if lib.starts_with("lib") {
136            println!(
137                "cargo:rustc-link-lib=static={}",
138                lib.strip_prefix("lib").unwrap()
139            );
140        } else {
141            println!("cargo:rustc-link-lib=static={}", lib);
142        }
143    }
144    println!("cargo:rustc-link-lib=static=cfltk");
145    println!("cargo:rustc-link-lib=static=fltk");
146    match target_os.as_str() {
147        "macos" => {
148            println!("cargo:rustc-link-lib=framework=Carbon");
149            println!("cargo:rustc-link-lib=framework=Cocoa");
150            println!("cargo:rustc-link-lib=framework=ApplicationServices");
151        }
152        "windows" => {
153            println!("cargo:rustc-link-lib=dylib=ws2_32");
154            println!("cargo:rustc-link-lib=dylib=comctl32");
155            println!("cargo:rustc-link-lib=dylib=gdi32");
156            println!("cargo:rustc-link-lib=dylib=oleaut32");
157            println!("cargo:rustc-link-lib=dylib=ole32");
158            println!("cargo:rustc-link-lib=dylib=uuid");
159            println!("cargo:rustc-link-lib=dylib=shell32");
160            println!("cargo:rustc-link-lib=dylib=advapi32");
161            println!("cargo:rustc-link-lib=dylib=comdlg32");
162            println!("cargo:rustc-link-lib=dylib=winspool");
163            println!("cargo:rustc-link-lib=dylib=user32");
164            println!("cargo:rustc-link-lib=dylib=kernel32");
165            println!("cargo:rustc-link-lib=dylib=odbc32");
166            if !cfg!(feature = "no-gdiplus") {
167                println!("cargo:rustc-link-lib=dylib=gdiplus");
168            }
169        }
170        "android" => {
171            println!("cargo:rustc-link-lib=log");
172            println!("cargo:rustc-link-lib=android");
173            println!("cargo:rustc-link-lib=c++_shared");
174        }
175        _ => {
176            println!("cargo:rustc-link-lib=dylib=pthread");
177            println!("cargo:rustc-link-lib=dylib=X11");
178            println!("cargo:rustc-link-lib=dylib=Xext");
179            println!("cargo:rustc-link-lib=dylib=Xinerama");
180            println!("cargo:rustc-link-lib=dylib=Xcursor");
181            println!("cargo:rustc-link-lib=dylib=Xrender");
182            println!("cargo:rustc-link-lib=dylib=Xfixes");
183            println!("cargo:rustc-link-lib=dylib=Xft");
184            println!("cargo:rustc-link-lib=dylib=fontconfig");
185            if !cfg!(feature = "no-pango") {
186                println!("cargo:rustc-link-lib=dylib=pango-1.0");
187                println!("cargo:rustc-link-lib=dylib=pangoxft-1.0");
188                println!("cargo:rustc-link-lib=dylib=gobject-2.0");
189                println!("cargo:rustc-link-lib=dylib=cairo");
190                println!("cargo:rustc-link-lib=dylib=pangocairo-1.0");
191            }
192        }
193    }
194}