Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Olena
pylene
Commits
24f26b4b
Commit
24f26b4b
authored
Jul 15, 2021
by
Baptiste Esteban
Committed by
Edwin Carlinet
Jul 15, 2021
Browse files
Add compilers in the CI + split Pylene-core into components
parent
d611ce4f
Changes
11
Hide whitespace changes
Inline
Side-by-side
.gitlab-ci.yml
View file @
24f26b4b
...
...
@@ -13,6 +13,7 @@ variables:
FEDORA_RAWHIDE
:
"
${CI_REGISTRY}/olena/pylene-dockers/fedora-rawhide"
FEDORA_31
:
"
${CI_REGISTRY}/olena/pylene-dockers/fedora-31"
FEDORA_32
:
"
${CI_REGISTRY}/olena/pylene-dockers/fedora-32"
FEDORA_34
:
"
${CI_REGISTRY}/olena/pylene-dockers/fedora-34"
CMAKE_BUILD_PARALLEL_LEVEL
:
6
CONAN_UPLOAD
:
"
https://artifactory.lrde.epita.fr/artifactory/api/conan/lrde-public@True"
CONAN_USERNAME
:
"
lrde"
...
...
@@ -92,6 +93,9 @@ distcheck-linux-gcc9-release:
CXX
:
"
g++"
CC
:
"
gcc"
CONAN_PROFILE
:
"
gcc-9"
rules
:
-
if
:
$CI_MERGE_REQUEST_ID
-
if
:
$CI_COMMIT_BRANCH == "master"
distcheck-linux-gcc9-debug-asan-ubsan
:
...
...
@@ -104,6 +108,12 @@ distcheck-linux-gcc9-debug-asan-ubsan:
CONAN_PROFILE
:
"
gcc-9"
CCFLAGS
:
-fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
CXXFLAGS
:
-fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
rules
:
-
if
:
$CI_COMMIT_BRANCH == "master"
-
if
:
$CI_MERGE_REQUEST_ID
when
:
never
-
when
:
manual
allow_failure
:
true
distcheck-linux-clang10-release
:
<<
:
*distcheck-linux-base
...
...
@@ -152,6 +162,51 @@ distcheck-linux-gcc10-debug:
CXXFLAGS
:
-fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
CONAN_PROFILE
:
"
gcc-10"
distcheck-linux-gcc11-release
:
<<
:
*distcheck-linux-base
image
:
${FEDORA_34}
variables
:
PYLENE_CONFIGURATION
:
"
Release"
CXX
:
"
g++"
CC
:
"
gcc"
CONAN_PROFILE
:
"
gcc-11"
rules
:
-
if
:
$CI_MERGE_REQUEST_ID
-
if
:
$CI_COMMIT_BRANCH == "master"
distcheck-linux-gcc11-debug
:
<<
:
*distcheck-linux-base
image
:
${FEDORA_34}
variables
:
PYLENE_CONFIGURATION
:
"
Debug"
CXX
:
"
g++"
CC
:
"
gcc"
CCFLAGS
:
-fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
CXXFLAGS
:
-fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
CONAN_PROFILE
:
"
gcc-11"
distcheck-linux-clang12-release
:
<<
:
*distcheck-linux-base
image
:
${FEDORA_34}
variables
:
PYLENE_CONFIGURATION
:
"
Release"
CXX
:
"
clang++"
CC
:
"
clang"
CONAN_PROFILE
:
"
clang-12"
rules
:
-
if
:
$CI_MERGE_REQUEST_ID
-
if
:
$CI_COMMIT_BRANCH == "master"
distcheck-linux-clang12-debug
:
<<
:
*distcheck-linux-base
image
:
${FEDORA_34}
variables
:
PYLENE_CONFIGURATION
:
"
Debug"
CXX
:
"
clang++"
CC
:
"
clang"
CCFLAGS
:
-fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
CXXFLAGS
:
-fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
CONAN_PROFILE
:
"
clang-12"
distcheck-linux-coverage
:
<<
:
*distcheck-linux-base
...
...
@@ -273,3 +328,14 @@ package clang-10:
variables
:
CONAN_BASE_PROFILE
:
clang-10
package gcc-11
:
extends
:
.package
image
:
${FEDORA_34}
variables
:
CONAN_BASE_PROFILE
:
gcc-11
package clang-12
:
extends
:
.package
image
:
${FEDORA_34}
variables
:
CONAN_BASE_PROFILE
:
clang-12
\ No newline at end of file
CMakeLists.txt
View file @
24f26b4b
...
...
@@ -132,7 +132,7 @@ target_link_libraries(Pylene INTERFACE Pylene::Core)
include
(
GNUInstallDirs
)
set
(
PyleneTargets Pylene Pylene-core Pylene-bp
)
set
(
PyleneTargets Pylene Pylene-core Pylene-bp
Pylene-io-freeimage
)
if
(
TARGET Pylene-numpy
)
list
(
APPEND PyleneTargets Pylene-numpy
)
endif
()
...
...
bench/CMakeLists.txt
View file @
24f26b4b
...
...
@@ -39,7 +39,7 @@ add_library(BenchImpl
set_target_properties
(
BenchImpl PROPERTIES COMPILE_FLAGS
${
STANDALONE_COMPILE_FLAGS
}
)
target_include_directories
(
BenchImpl PUBLIC include
)
target_link_libraries
(
BenchImpl PUBLIC Pylene::
Pylen
e
)
target_link_libraries
(
BenchImpl PUBLIC Pylene::
Core Pylene::IO-freeimag
e
)
add_subdirectory
(
tests
)
...
...
conanfile.py
View file @
24f26b4b
...
...
@@ -16,6 +16,7 @@ class Pylene(ConanFile):
"shared"
:
False
,
"fPIC"
:
False
,
"gtest:shared"
:
False
,
"boost:header_only"
:
True
,
}
generators
=
[
"cmake"
,
"cmake_paths"
,
"cmake_find_package"
]
...
...
@@ -24,10 +25,6 @@ class Pylene(ConanFile):
build_requires
=
[
"gtest/[>=1.10]"
,
"benchmark/[>=1.5.0]"
,
# For now boost is too heavy and is not based on components
# Such a dependancy brings linktime overhead because too many libraries are linked
# "boost/1.73.0"
]
requires
=
[
...
...
@@ -35,6 +32,7 @@ class Pylene(ConanFile):
"fmt/6.0.0"
,
"tbb/2020.0"
,
"xsimd/7.4.6"
,
"boost/1.75.0"
]
def
_build_python
(
self
):
...
...
@@ -66,13 +64,22 @@ class Pylene(ConanFile):
self
.
cpp_info
.
names
[
"cmake_find_package"
]
=
"Pylene"
self
.
cpp_info
.
names
[
"cmake_find_package_multi"
]
=
"Pylene"
self
.
cpp_info
.
components
[
"Core"
].
system_libs
.
append
(
"freeimage"
)
# Core component
self
.
cpp_info
.
components
[
"Core"
].
names
[
"cmake_find_package"
]
=
"Core"
self
.
cpp_info
.
components
[
"Core"
].
names
[
"cmake_find_package_multi"
]
=
"Core"
self
.
cpp_info
.
components
[
"Core"
].
libs
=
[
"Pylene-core"
]
self
.
cpp_info
.
components
[
"Core"
].
includedirs
=
[
"include"
]
self
.
cpp_info
.
components
[
"Core"
].
requires
=
[
"range-v3::range-v3"
,
"fmt::fmt"
,
"tbb::tbb"
,
"xsimd::xsimd"
]
self
.
cpp_info
.
components
[
"Core"
].
requires
=
[
"range-v3::range-v3"
,
"fmt::fmt"
,
"tbb::tbb"
,
"xsimd::xsimd"
,
"boost::headers"
]
# IO component
self
.
cpp_info
.
components
[
"IO-freeimage"
].
system_libs
.
append
(
"freeimage"
)
self
.
cpp_info
.
components
[
"IO-freeimage"
].
names
[
"cmake_find_package"
]
=
"IO-freeimage"
self
.
cpp_info
.
components
[
"IO-freeimage"
].
names
[
"cmake_find_package_multi"
]
=
"IO-freeimage"
self
.
cpp_info
.
components
[
"IO-freeimage"
].
libs
=
[
"Pylene-io-freeimage"
]
self
.
cpp_info
.
components
[
"IO-freeimage"
].
includedirs
=
[
"include"
]
self
.
cpp_info
.
components
[
"IO-freeimage"
].
requires
=
[
"Core"
]
# Pylene-numpy component
if
self
.
_build_python
():
self
.
cpp_info
.
components
[
"Pylene-numpy"
].
names
[
"cmake_find_pakage_multi"
]
=
"Pylene-numpy"
self
.
cpp_info
.
components
[
"Pylene-numpy"
].
names
[
"cmake_find_pakage"
]
=
"Pylene-numpy"
...
...
doc/CMakeLists.txt
View file @
24f26b4b
find_package
(
Doxygen
)
find_package
(
Sphinx
)
find_package
(
Boost COMPONENTS program_options REQUIRED
)
add_subdirectory
(
source/snippets
)
...
...
doc/source/snippets/CMakeLists.txt
View file @
24f26b4b
...
...
@@ -73,7 +73,7 @@ target_link_libraries(doc-lib Pylene::Core)
link_libraries
(
Pylene::Core
)
link_libraries
(
Pylene::Core
Pylene::IO-freeimage
)
link_libraries
(
doc-lib
)
add_executable
(
alphatree_example alphatree_example.cpp
)
...
...
@@ -89,11 +89,4 @@ add_executable(cdt cdt.cpp)
add_executable
(
first_start_1 first_start_1.cpp
)
add_executable
(
intro-1 intro-1.cpp
)
target_compile_definitions
(
erosion-cli PRIVATE BOOST_ALL_NO_LIB
)
# for program_options, need to separate CONAN and regular FindBoost
if
(
TARGET Boost::program_options
)
target_link_libraries
(
erosion-cli PRIVATE Boost::program_options
)
elseif
(
TARGET Boost::Boost
)
target_link_libraries
(
erosion-cli PRIVATE Boost::Boost
)
endif
()
\ No newline at end of file
target_compile_definitions
(
erosion-cli PRIVATE BOOST_ALL_NO_LIB
)
\ No newline at end of file
doc/source/snippets/erosion-cli.cpp
View file @
24f26b4b
#include <mln/core/image/ndimage.hpp>
#include <mln/core/se/disc.hpp>
#include <mln/core/se/rect2d.hpp>
#include <mln/morpho/closing.hpp>
#include <mln/morpho/dilation.hpp>
#include <mln/morpho/erosion.hpp>
#include <mln/morpho/opening.hpp>
#include <mln/morpho/median_filter.hpp>
#include <mln/morpho/gradient.hpp>
#include <mln/morpho/median_filter.hpp>
#include <mln/morpho/opening.hpp>
#include <mln/io/imread.hpp>
#include <mln/io/imsave.hpp>
#include <algorithm>
#include <boost/program_options.hpp>
#include <cctype>
#include <cstdlib>
#include <iostream>
#include <string>
namespace
po
=
boost
::
program_options
;
enum
se_type
{
kSquare
,
kDisc
,
kDiamond
};
int
tolower_safe
(
int
c
)
{
return
std
::
tolower
(
static_cast
<
unsigned
char
>
(
c
));
}
std
::
istream
&
operator
>>
(
std
::
istream
&
in
,
se_type
&
se
)
enum
class
morpho_op_type
{
std
::
string
token
;
in
>>
token
;
std
::
transform
(
token
.
begin
(),
token
.
end
(),
token
.
begin
(),
tolower_safe
);
if
(
token
==
"square"
)
se
=
kSquare
;
else
if
(
token
==
"disc"
)
se
=
kDisc
;
else
if
(
token
==
"diamond"
)
se
=
kDiamond
;
else
throw
po
::
invalid_option_value
(
"Invalid SE"
);
return
in
;
}
enum
morpho_op_type
{
kErosion
,
kErosion
=
0
,
kDilation
,
kOpening
,
kClosing
,
...
...
@@ -62,110 +29,113 @@ enum morpho_op_type
kExternalGradient
};
std
::
istream
&
operator
>>
(
std
::
istream
&
in
,
morpho_op_type
&
se
)
enum
class
se_type
{
kSquare
=
0
,
kDisc
};
morpho_op_type
get_morpho_op
(
char
*
arg
)
{
std
::
string
token
;
in
>>
token
;
std
::
transform
(
token
.
begin
(),
token
.
end
(),
token
.
begin
(),
tolower_safe
);
if
(
token
==
"erosion"
)
se
=
kErosion
;
else
if
(
token
==
"dilation"
)
se
=
kDilation
;
else
if
(
token
==
"opening"
)
se
=
kOpening
;
else
if
(
token
==
"closing"
)
se
=
kClosing
;
else
if
(
token
==
"median"
)
se
=
kMedian
;
else
if
(
token
==
"gradient"
)
se
=
kGradient
;
else
if
(
token
==
"ext_gradient"
)
se
=
kExternalGradient
;
else
if
(
token
==
"int_gradient"
)
se
=
kInternalGradient
;
const
std
::
string
str
(
arg
);
if
(
str
==
"erosion"
)
return
morpho_op_type
::
kErosion
;
else
if
(
str
==
"dilation"
)
return
morpho_op_type
::
kDilation
;
else
if
(
str
==
"opening"
)
return
morpho_op_type
::
kOpening
;
else
if
(
str
==
"closing"
)
return
morpho_op_type
::
kClosing
;
else
if
(
str
==
"median"
)
return
morpho_op_type
::
kMedian
;
else
if
(
str
==
"gradient"
)
return
morpho_op_type
::
kGradient
;
else
if
(
str
==
"int_gradient"
)
return
morpho_op_type
::
kInternalGradient
;
else
if
(
str
==
"ext_gradient"
)
return
morpho_op_type
::
kExternalGradient
;
else
throw
po
::
invalid_option_value
(
"Invalid Operator"
);
return
in
;
throw
std
::
invalid_argument
(
"Invalid input morphological operation"
);
}
struct
exec_params_type
se_type
get_se
(
char
*
arg
)
{
se_type
se
;
morpho_op_type
op
;
int
size
;
};
const
std
::
string
str
(
arg
);
if
(
str
==
"square"
)
return
se_type
::
kSquare
;
else
if
(
str
==
"disk"
)
return
se_type
::
kDisc
;
else
throw
std
::
invalid_argument
(
"Invalid input structuring element"
);
}
int
main
(
int
argc
,
char
**
argv
)
template
<
typename
SE
>
mln
::
image2d
<
std
::
uint8_t
>
process
(
mln
::
image2d
<
std
::
uint8_t
>
img
,
morpho_op_type
op
,
SE
se
)
{
po
::
options_description
desc
(
"Allowed options"
);
po
::
positional_options_description
p
;
p
.
add
(
"operator"
,
1
).
add
(
"se"
,
1
).
add
(
"size"
,
1
).
add
(
"input"
,
1
).
add
(
"output"
,
1
);
desc
.
add_options
()(
"help"
,
"produce help message"
)(
"operator"
,
po
::
value
<
morpho_op_type
>
()
->
required
(),
""
)(
"se"
,
po
::
value
<
se_type
>
()
->
required
(),
""
)(
"size"
,
po
::
value
<
int
>
()
->
required
(),
"Size of the SE."
)(
"input"
,
po
::
value
<
std
::
string
>
()
->
required
(),
"Input image (8u or rgb8)"
)(
"output"
,
po
::
value
<
std
::
string
>
()
->
required
(),
"Output image (8u or rgb8)"
);
po
::
variables_map
vm
;
int
size
;
try
using
namespace
mln
::
morpho
;
switch
(
op
)
{
po
::
store
(
po
::
command_line_parser
(
argc
,
argv
).
options
(
desc
).
positional
(
p
).
run
(),
vm
);
po
::
notify
(
vm
);
size
=
vm
[
"size"
].
as
<
int
>
();
if
(
size
<
1
||
size
%
2
==
0
)
{
std
::
cerr
<<
"Size must be positive and odd.
\n
"
;
return
1
;
}
case
morpho_op_type
::
kErosion
:
return
erosion
(
img
,
se
);
break
;
case
morpho_op_type
::
kDilation
:
return
dilation
(
img
,
se
);
break
;
case
morpho_op_type
::
kOpening
:
return
opening
(
img
,
se
);
break
;
case
morpho_op_type
::
kClosing
:
return
closing
(
img
,
se
);
break
;
case
morpho_op_type
::
kMedian
:
return
median_filter
(
img
,
se
,
mln
::
extension
::
bm
::
mirror
{});
break
;
case
morpho_op_type
::
kGradient
:
return
gradient
(
img
,
se
);
break
;
case
morpho_op_type
::
kInternalGradient
:
return
internal_gradient
(
img
,
se
);
break
;
case
morpho_op_type
::
kExternalGradient
:
return
external_gradient
(
img
,
se
);
break
;
}
catch
(...)
return
mln
::
image2d
<
std
::
uint8_t
>
();
}
int
main
(
int
argc
,
char
*
argv
[])
{
using
namespace
mln
;
if
(
argc
!=
6
)
{
std
::
cout
<<
"Usage: "
<<
argv
[
0
]
<<
" [-h,--help] OPERATOR SE size input output
\n
"
"OPERATOR
\t
Morphological operation to perform [erosion | dilation | opening | closing | median | gradient | ext_gradient | int_gradient]
\n
"
"SE
\t
Structuring element to use [square | disc | diamond]
\n
"
<<
" OPERATOR SE size input output
\n
"
"OPERATOR
\t
Morphological operation to perform [erosion | dilation | opening | closing | median | "
"gradient | ext_gradient | int_gradient]
\n
"
"SE
\t
Structuring element to use [square | disc]
\n
"
"size
\t
Size of the SE
\n
"
"input
\t
Input image (u8)
\n
"
"output
\t
Output image (u8)
\n
"
;
return
1
;
}
mln
::
image2d
<
uint8_t
>
input
,
output
;
mln
::
io
::
imread
(
vm
[
"input"
].
as
<
std
::
string
>
(),
input
);
const
auto
input_op
=
get_morpho_op
(
argv
[
1
]);
const
auto
input_se
=
get_se
(
argv
[
2
]);
const
auto
size
=
std
::
atoi
(
argv
[
3
]);
mln
::
image2d
<
std
::
uint8_t
>
img
;
mln
::
io
::
imread
(
argv
[
4
],
img
);
mln
::
se
::
rect2d
nbh
(
size
,
size
);
if
(
size
<
1
||
size
%
2
==
0
)
throw
std
::
invalid_argument
(
"Structuring element size must be positive and odd"
);
switch
(
vm
[
"operator"
].
as
<
morpho_op_type
>
())
{
case
kErosion
:
output
=
mln
::
morpho
::
erosion
(
input
,
nbh
);
break
;
case
kDilation
:
output
=
mln
::
morpho
::
dilation
(
input
,
nbh
);
break
;
case
kOpening
:
output
=
mln
::
morpho
::
opening
(
input
,
nbh
);
break
;
case
kClosing
:
output
=
mln
::
morpho
::
closing
(
input
,
nbh
);
break
;
case
kMedian
:
output
=
mln
::
morpho
::
median_filter
(
input
,
nbh
,
mln
::
extension
::
bm
::
mirror
{});
break
;
case
kGradient
:
output
=
mln
::
morpho
::
gradient
(
input
,
nbh
);
break
;
case
kExternalGradient
:
output
=
mln
::
morpho
::
external_gradient
(
input
,
nbh
);
break
;
case
kInternalGradient
:
output
=
mln
::
morpho
::
internal_gradient
(
input
,
nbh
);
break
;
}
mln
::
image2d
<
std
::
uint8_t
>
out
;
if
(
input_se
==
se_type
::
kDisc
)
out
=
process
(
img
,
input_op
,
se
::
disc
(
size
));
else
out
=
process
(
img
,
input_op
,
se
::
rect2d
(
size
,
size
));
mln
::
io
::
imsave
(
output
,
vm
[
"output"
].
as
<
std
::
string
>
());
}
mln
::
io
::
imsave
(
out
,
argv
[
5
]);
return
0
;
}
\ No newline at end of file
pylene/CMakeLists.txt
View file @
24f26b4b
...
...
@@ -42,8 +42,6 @@ target_include_directories(Pylene-core PUBLIC
target_include_directories
(
Pylene-core SYSTEM PUBLIC $<BUILD_INTERFACE:
${
Boost_INCLUDE_DIRS
}
>
)
target_link_libraries
(
Pylene-core PUBLIC range-v3::range-v3 xsimd::xsimd
)
target_link_libraries
(
Pylene-core PUBLIC fmt::fmt
)
target_link_libraries
(
Pylene-core PRIVATE FreeImage::FreeImage
)
# Set sources
#file(GLOB_RECURSE sources "include/mln/*.hpp")
...
...
@@ -79,10 +77,7 @@ target_sources(Pylene-core PRIVATE
src/core/se/rect2d.cpp
src/core/trace.cpp
src/core/traverse2d.cpp
src/io/freeimage_plugin.cpp
src/io/imprint.cpp
src/io/imread.cpp
src/io/io.cpp
src/morpho/block_running_max.cpp
src/morpho/component_tree.cpp
src/morpho/hvector.cpp
...
...
@@ -93,12 +88,27 @@ target_sources(Pylene-core PRIVATE
src/morpho/filters2d.cpp
)
add_library
(
Pylene-io-freeimage
)
add_library
(
Pylene::IO-freeimage ALIAS Pylene-io-freeimage
)
target_sources
(
Pylene-io-freeimage PRIVATE
src/io/freeimage_plugin.cpp
src/io/imread.cpp
src/io/io.cpp
)
target_compile_features
(
Pylene-io-freeimage PUBLIC cxx_std_20
)
target_include_directories
(
Pylene-io-freeimage PUBLIC
$<BUILD_INTERFACE:
${
CMAKE_CURRENT_SOURCE_DIR
}
/include>
$<INSTALL_INTERFACE:include>
)
target_link_libraries
(
Pylene-io-freeimage PUBLIC FreeImage::FreeImage Pylene-core
)
# Compiler configurations
target_compile_features
(
Pylene-core PUBLIC cxx_std_20
)
if
(
CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0
)
target_compile_options
(
Pylene-bp PUBLIC -fconcepts
)
target_compile_options
(
Pylene-core PUBLIC -fconcepts
)
target_compile_options
(
Pylene-io-freeimage PUBLIC -fconcepts
)
endif
()
# IDE configuration
...
...
test_package/CMakeLists.txt
View file @
24f26b4b
project
(
PyleneTest
)
cmake_minimum_required
(
VERSION 3.11
)
find_package
(
Pylene REQUIRED COMPONENTS Core
)
find_package
(
Pylene REQUIRED COMPONENTS Core
IO-freeimage
)
add_executable
(
main main.cpp
)
target_link_libraries
(
main Pylene::Core
)
target_link_libraries
(
main Pylene::Core
Pylene::IO-freeimage
)
if
(
WITH_PYLENE_NUMPY
)
find_package
(
pybind11 REQUIRED
)
...
...
tests/CMakeLists.txt
View file @
24f26b4b
...
...
@@ -12,7 +12,7 @@ function(add_core_test Executable)
set
(
core_test_NAME
${
Executable
}
)
add_executable
(
${
core_test_NAME
}
${
core_test_SOURCES
}
)
target_link_libraries
(
${
core_test_NAME
}
PRIVATE Fixtures::ImagePath Fixtures::ImageCompare Pylene::
Pylen
e GTest::GTest
)
target_link_libraries
(
${
core_test_NAME
}
PRIVATE Fixtures::ImagePath Fixtures::ImageCompare Pylene::
Core Pylene::IO-freeimag
e GTest::GTest
)
set_target_properties
(
${
core_test_NAME
}
PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${
CMAKE_BINARY_DIR
}
/tests
)
add_test
(
NAME
${
core_test_NAME
}
COMMAND
${
core_test_NAME
}
--gtest_output=xml:
${
core_test_NAME
}
.xml WORKING_DIRECTORY
${
CMAKE_BINARY_DIR
}
/tests
)
...
...
tests/contrib/CMakeLists.txt
View file @
24f26b4b
add_executable
(
meanshift meanshift/meanshift.cpp
)
target_link_libraries
(
meanshift Pylene::
Pylen
e
)
target_link_libraries
(
meanshift Pylene::
IO-freeimag
e
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment