1 // Copyright 2011-2012 Renato Tegon Forti
2 // Copyright 2015 Antony Polukhin
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
8 // For more information, see http://www.boost.org
10 #include "../example/b2_workarounds.hpp"
11 #include <boost/dll.hpp>
12 #include <boost/core/lightweight_test.hpp>
13 #include <boost/filesystem.hpp>
17 inline boost::filesystem::path
drop_version(const boost::filesystem::path
& lhs
) {
18 boost::filesystem::path ext
= lhs
.filename().extension();
19 if (ext
.native().size() > 1 && std::isdigit(ext
.string()[1])) {
21 ext
.replace_extension().replace_extension().replace_extension();
28 inline bool lib_path_equal(const boost::filesystem::path
& lhs
, const boost::filesystem::path
& rhs
) {
29 const bool res
= (drop_version(lhs
).filename() == drop_version(rhs
).filename());
31 std::cerr
<< "lhs != rhs: " << lhs
<< " != " << rhs
<< '\n';
36 struct fs_copy_guard
{
37 const boost::filesystem::path actual_path_
;
40 inline explicit fs_copy_guard(const boost::filesystem::path
& shared_library_path
)
41 : actual_path_( drop_version(shared_library_path
) )
42 , same_(actual_path_
== shared_library_path
)
45 boost::system::error_code ignore
;
46 boost::filesystem::remove(actual_path_
, ignore
);
47 boost::filesystem::copy(shared_library_path
, actual_path_
, ignore
);
51 inline ~fs_copy_guard() {
53 boost::system::error_code ignore
;
54 boost::filesystem::remove(actual_path_
, ignore
);
59 // Disgusting workarounds for b2 on Windows platform
60 inline boost::filesystem::path
do_find_correct_libs_path(int argc
, char* argv
[], const char* lib_name
) {
61 boost::filesystem::path ret
;
63 for (int i
= 1; i
< argc
; ++i
) {
65 if (ret
.string().find(lib_name
) != std::string::npos
&& b2_workarounds::is_shared_library(ret
)) {
73 int main(int argc
, char* argv
[])
75 using namespace boost::dll
;
77 BOOST_TEST(argc
>= 3);
78 boost::filesystem::path shared_library_path
= do_find_correct_libs_path(argc
, argv
, "test_library");
79 std::cout
<< "Library: " << shared_library_path
;
82 shared_library
sl(shared_library_path
);
83 BOOST_TEST(sl
.is_loaded());
84 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
87 BOOST_TEST(!sl2
.is_loaded());
91 BOOST_TEST(!sl
.is_loaded());
93 BOOST_TEST(sl2
.is_loaded());
97 BOOST_TEST(sl
.is_loaded());
99 BOOST_TEST(sl2
.is_loaded());
101 BOOST_TEST(sl2
.location() == sl
.location());
104 BOOST_TEST(sl
.is_loaded());
106 BOOST_TEST(sl2
.is_loaded());
108 BOOST_TEST(sl2
.location() == sl
.location());
111 BOOST_TEST(sl
.is_loaded());
113 BOOST_TEST(sl2
.is_loaded());
115 BOOST_TEST(sl2
.location() == sl
.location());
117 // Assigning an empty shared library
118 sl2
.assign(shared_library());
119 BOOST_TEST(sl
.is_loaded());
121 BOOST_TEST(!sl2
.is_loaded());
123 boost::system::error_code ec
;
124 BOOST_TEST(sl2
.location(ec
) != sl
.location());
129 boost::system::error_code ec
;
130 shared_library
sl(shared_library_path
, ec
);
131 BOOST_TEST(sl
.is_loaded());
134 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
135 BOOST_TEST(lib_path_equal(sl
.location(ec
), shared_library_path
));
138 // Checking self assignment #1
140 BOOST_TEST(sl
.is_loaded());
143 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
144 BOOST_TEST(lib_path_equal(sl
.location(ec
), shared_library_path
));
146 // Checking self assignment #2
148 BOOST_TEST(sl
.is_loaded());
151 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
152 BOOST_TEST(lib_path_equal(sl
.location(ec
), shared_library_path
));
157 BOOST_TEST(!sl
.is_loaded());
162 shared_library
sl2(sl
);
173 sl
.load(shared_library_path
);
174 BOOST_TEST(sl
.is_loaded());
176 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
181 boost::system::error_code ec
;
182 sl
.load(shared_library_path
, ec
);
183 BOOST_TEST(sl
.is_loaded());
186 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
190 shared_library
sl(shared_library_path
, load_mode::load_with_altered_search_path
);
191 BOOST_TEST(sl
.is_loaded());
193 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
197 boost::system::error_code ec
;
198 shared_library
sl(shared_library_path
, load_mode::load_with_altered_search_path
, ec
);
199 BOOST_TEST(sl
.is_loaded());
202 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
203 BOOST_TEST(lib_path_equal(sl
.location(ec
), shared_library_path
));
208 boost::system::error_code ec
;
209 shared_library
sl(shared_library_path
, load_mode::search_system_folders
, ec
);
210 BOOST_TEST(sl
.is_loaded());
213 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
214 BOOST_TEST(lib_path_equal(sl
.location(ec
), shared_library_path
));
221 boost::dll::shared_library("winmm.dll");
223 boost::dll::shared_library("libdl.so");
232 boost::dll::shared_library("winmm", load_mode::search_system_folders
| load_mode::append_decorations
);
234 boost::dll::shared_library("dl", boost::dll::load_mode::search_system_folders
| load_mode::append_decorations
);
243 sl
.load(shared_library_path
, load_mode::load_with_altered_search_path
);
244 BOOST_TEST(sl
.is_loaded());
246 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
251 boost::system::error_code ec
;
252 sl
.load(shared_library_path
, load_mode::load_with_altered_search_path
, ec
);
253 BOOST_TEST(sl
.is_loaded());
255 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
259 shared_library
sl(shared_library_path
, load_mode::rtld_lazy
| load_mode::rtld_global
);
260 BOOST_TEST(sl
.is_loaded());
262 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
266 shared_library
sl(shared_library_path
, load_mode::rtld_local
);
267 BOOST_TEST(sl
.is_loaded());
269 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
273 shared_library
sl(shared_library_path
, load_mode::rtld_now
);
274 BOOST_TEST(sl
.is_loaded());
276 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
280 fs_copy_guard
guard(shared_library_path
);
282 boost::filesystem::path platform_independent_path
= guard
.actual_path_
;
283 platform_independent_path
.replace_extension();
284 if (platform_independent_path
.filename().wstring().find(L
"lib") == 0) {
285 platform_independent_path
286 = platform_independent_path
.parent_path() / platform_independent_path
.filename().wstring().substr(3);
288 std::cerr
<< "platform_independent_path: " << platform_independent_path
<< '\n';
290 shared_library
sl(platform_independent_path
, load_mode::append_decorations
);
291 BOOST_TEST(sl
.is_loaded());
293 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
296 BOOST_TEST(!sl
.is_loaded());
301 shared_library
sl(shared_library_path
, load_mode::rtld_now
| load_mode::rtld_global
| load_mode::load_with_altered_search_path
);
302 BOOST_TEST(sl
.is_loaded());
307 boost::system::error_code ec
;
308 shared_library
sl(shared_library_path
, load_mode::rtld_lazy
| load_mode::rtld_global
, ec
);
309 BOOST_TEST(sl
.is_loaded());
312 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
317 sl
.load(shared_library_path
, load_mode::rtld_lazy
| load_mode::rtld_global
);
318 BOOST_TEST(sl
.is_loaded());
320 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
324 { // Non-default flags with assignment
325 shared_library
sl(shared_library_path
,
326 load_mode::rtld_now
| load_mode::rtld_global
| load_mode::load_with_altered_search_path
| load_mode::rtld_deepbind
328 BOOST_TEST(sl
.is_loaded());
331 boost::system::error_code ec
;
332 shared_library
sl2(sl
, ec
);
334 BOOST_TEST(sl
.is_loaded());
336 BOOST_TEST(sl2
.is_loaded());
338 BOOST_TEST(sl2
.location() == sl
.location());
340 shared_library
sl3(sl
);
341 BOOST_TEST(sl
.is_loaded());
343 BOOST_TEST(sl3
.is_loaded());
349 BOOST_TEST(sl
.is_loaded());
351 BOOST_TEST(sl4
.is_loaded());
355 { // Non-default flags with assignment and error_code
356 boost::system::error_code ec
;
357 shared_library
sl(shared_library_path
, load_mode::rtld_lazy
| load_mode::rtld_global
, ec
);
358 BOOST_TEST(sl
.is_loaded());
361 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
363 shared_library
sl2(sl
, ec
);
365 BOOST_TEST(sl
.is_loaded());
367 BOOST_TEST(sl2
.is_loaded());
369 BOOST_TEST(sl2
.location() == sl
.location());
371 shared_library
sl3(sl
);
372 BOOST_TEST(sl
.is_loaded());
374 BOOST_TEST(sl3
.is_loaded());
376 BOOST_TEST(sl3
.location() == sl
.location());
380 shared_library
sl(program_location());
381 BOOST_TEST(sl
.is_loaded());
383 std::cout
<< "\nProgram location: " << program_location();
384 std::cout
<< "\nLibrary location: " << sl
.location();
385 BOOST_TEST( boost::filesystem::equivalent(sl
.location(), program_location()) );
387 boost::system::error_code ec
;
388 shared_library
sl2(program_location());
389 BOOST_TEST(sl2
.is_loaded());
390 BOOST_TEST( boost::filesystem::equivalent(sl2
.location(), program_location()) );
394 BOOST_TEST(sl
== sl2
);
395 BOOST_TEST(!(sl
< sl2
|| sl2
<sl
));
396 BOOST_TEST(!(sl
!= sl2
));
398 sl
.load(shared_library_path
);
399 BOOST_TEST(sl
!= sl2
);
400 BOOST_TEST(sl
< sl2
|| sl2
<sl
);
401 BOOST_TEST(!(sl
== sl2
));
405 BOOST_TEST(sl
!= sl2
);
406 BOOST_TEST(sl
< sl2
|| sl2
<sl
);
407 BOOST_TEST(!(sl
== sl2
));
411 BOOST_TEST(sl
== sl2
);
412 BOOST_TEST(!(sl
< sl2
|| sl2
<sl
));
413 BOOST_TEST(!(sl
!= sl2
));
416 sl
.load(program_location());
418 BOOST_TEST(sl
== sl2
);
419 BOOST_TEST(sl
.location() == sl2
.location());
424 boost::system::error_code ec
;
425 sl
.load(shared_library_path
, load_mode::rtld_lazy
| load_mode::rtld_global
, ec
);
426 BOOST_TEST(sl
.is_loaded());
429 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
431 sl
.load(program_location());
432 BOOST_TEST(sl
.is_loaded());
435 sl
.load(program_location());
436 BOOST_TEST(sl
.is_loaded());
443 boost::system::error_code ec
;
444 sl
.load(program_location());
445 BOOST_TEST(sl
.is_loaded());
451 shared_library
sl(shared_library_path
);
452 BOOST_TEST(sl
.is_loaded());
454 BOOST_TEST(lib_path_equal(sl
.location(), shared_library_path
));
456 BOOST_TEST(!sl
.is_loaded());
461 { // error_code load calls test
462 boost::system::error_code ec
;
463 shared_library
sl(shared_library_path
/ "dir_that_does_not_exist", ec
);
465 BOOST_TEST(!sl
.is_loaded());
468 boost::filesystem::path
bad_path(shared_library_path
);
469 bad_path
+= ".1.1.1.1.1.1";
470 sl
.load(bad_path
, ec
);
472 BOOST_TEST(!sl
.is_loaded());
475 sl
.load(shared_library_path
, ec
);
477 BOOST_TEST(sl
.is_loaded());
480 shared_library
sl2(bad_path
, ec
);
482 BOOST_TEST(!sl2
.is_loaded());
485 shared_library
sl3(shared_library_path
, ec
);
487 BOOST_TEST(sl3
.is_loaded());
492 BOOST_TEST(!sl
.is_loaded());
497 shared_library_path
= do_find_correct_libs_path(argc
, argv
, "library1");
498 fs_copy_guard
guard(shared_library_path
);
499 shared_library
starts_with_lib(
500 boost::filesystem::path(guard
.actual_path_
).replace_extension(),
501 load_mode::append_decorations
504 starts_with_lib
.load(
505 boost::filesystem::path(guard
.actual_path_
).replace_extension(),
506 load_mode::append_decorations
509 return boost::report_errors();