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}