1
- from conan import ConanFile
2
- from conan .errors import ConanInvalidConfiguration
3
- from conan .tools .files import get , rmdir
4
- from conan .tools .scm import Version
5
- from conans import AutoToolsBuildEnvironment , tools
6
- import contextlib
7
- import functools
8
1
import os
9
2
10
- required_conan_version = ">=1.33.0"
3
+ from conan import ConanFile
4
+ from conan .tools .build import cross_building
5
+ from conan .tools .env import VirtualBuildEnv , VirtualRunEnv , Environment
6
+ from conan .tools .files import get , rmdir , export_conandata_patches , apply_conandata_patches , copy , replace_in_file , rm , save
7
+ from conan .tools .gnu import AutotoolsToolchain , Autotools , AutotoolsDeps
8
+ from conan .tools .layout import basic_layout
9
+ from conan .tools .microsoft import unix_path , is_msvc
10
+
11
+ required_conan_version = ">=1.53.0"
11
12
12
13
13
14
class LibIdnConan (ConanFile ):
@@ -17,6 +18,8 @@ class LibIdnConan(ConanFile):
17
18
topics = ("libidn" , "encode" , "decode" , "internationalized" , "domain" , "name" )
18
19
license = "GPL-3.0-or-later"
19
20
url = "https://github.com/conan-io/conan-center-index"
21
+
22
+ package_type = "library"
20
23
settings = "os" , "arch" , "compiler" , "build_type"
21
24
options = {
22
25
"shared" : [True , False ],
@@ -29,117 +32,140 @@ class LibIdnConan(ConanFile):
29
32
"threads" : True ,
30
33
}
31
34
32
- @property
33
- def _source_subfolder (self ):
34
- return "source_subfolder"
35
-
36
35
@property
37
36
def _settings_build (self ):
38
37
return getattr (self , "settings_build" , self .settings )
39
38
40
39
def export_sources (self ):
41
- for patch in self .conan_data .get ("patches" , {}).get (self .version , []):
42
- self .copy (patch ["patch_file" ])
40
+ export_conandata_patches (self )
43
41
44
42
def config_options (self ):
45
43
if self .settings .os == "Windows" :
46
44
del self .options .fPIC
47
45
48
46
def configure (self ):
49
47
if self .options .shared :
50
- del self .options .fPIC
51
- del self .settings .compiler .libcxx
52
- del self .settings .compiler .cppstd
48
+ self .options .rm_safe ("fPIC" )
49
+ self .settings .rm_safe ("compiler.libcxx" )
50
+ self .settings .rm_safe ("compiler.cppstd" )
51
+
52
+ def layout (self ):
53
+ basic_layout (self , src_folder = "src" )
53
54
54
55
def requirements (self ):
55
56
self .requires ("libiconv/1.17" )
56
57
57
- def validate (self ):
58
- if self .settings .os == "Windows" and self .options .shared :
59
- raise ConanInvalidConfiguration ("Shared libraries are not supported on Windows due to libtool limitation" )
60
-
61
58
def build_requirements (self ):
62
- if self ._settings_build .os == "Windows" and not tools .get_env ("CONAN_BASH_PATH" ):
63
- self .build_requires ("msys2/cci.latest" )
64
- if self .settings .compiler == "Visual Studio" :
65
- self .build_requires ("automake/1.16.5" )
59
+ if self ._settings_build .os == "Windows" :
60
+ self .win_bash = True
61
+ if not self .conf .get ("tools.microsoft.bash:path" , check_type = str ):
62
+ self .tool_requires ("msys2/cci.latest" )
63
+ if is_msvc (self ):
64
+ self .tool_requires ("automake/1.16.5" )
66
65
67
66
def source (self ):
68
- get (self , ** self .conan_data ["sources" ][self .version ],
69
- destination = self ._source_subfolder , strip_root = True )
70
-
71
- @contextlib .contextmanager
72
- def _build_context (self ):
73
- if self .settings .compiler == "Visual Studio" :
74
- with tools .vcvars (self ):
75
- env = {
76
- "CC" : "{} cl -nologo" .format (tools .unix_path (self .deps_user_info ["automake" ].compile )),
77
- "CXX" : "{} cl -nologo" .format (tools .unix_path (self .deps_user_info ["automake" ].compile )),
78
- "LD" : "{} link -nologo" .format (tools .unix_path (self .deps_user_info ["automake" ].compile )),
79
- "AR" : "{} lib" .format (tools .unix_path (self .deps_user_info ["automake" ].ar_lib )),
80
- }
81
- with tools .environment_append (env ):
82
- yield
83
- else :
84
- yield
67
+ get (self , ** self .conan_data ["sources" ][self .version ], strip_root = True )
68
+
69
+ def generate (self ):
70
+ env = VirtualBuildEnv (self )
71
+ env .generate ()
72
+
73
+ if not cross_building (self ):
74
+ env = VirtualRunEnv (self )
75
+ env .generate (scope = "build" )
85
76
86
- @functools .lru_cache (1 )
87
- def _configure_autotools (self ):
88
- autotools = AutoToolsBuildEnvironment (self , win_bash = tools .os_info .is_windows )
89
- autotools .libs = []
77
+ tc = AutotoolsToolchain (self )
90
78
if not self .options .shared :
91
- autotools .defines .append ("LIBIDN_STATIC" )
92
- if self .settings .compiler == "Visual Studio" :
93
- if Version (self .settings .compiler .version ) >= "12" :
94
- autotools .flags .append ("-FS" )
95
- autotools .link_flags .extend ("-L{}" .format (p .replace ("\\ " , "/" )) for p in self .deps_cpp_info .lib_paths )
79
+ tc .extra_defines .append ("LIBIDN_STATIC" )
96
80
yes_no = lambda v : "yes" if v else "no"
97
- conf_args = [
98
- "--enable-shared={}" .format (yes_no (self .options .shared )),
99
- "--enable-static={}" .format (yes_no (not self .options .shared )),
81
+ tc .configure_args += [
100
82
"--enable-threads={}" .format (yes_no (self .options .threads )),
101
- "--with-libiconv-prefix={}" .format (tools .unix_path (self .deps_cpp_info ["libiconv" ].rootpath )),
83
+ "--with-libiconv-prefix={}" .format (unix_path (self , self .dependencies ["libiconv" ].package_folder )),
84
+ "--disable-csharp" ,
102
85
"--disable-nls" ,
103
86
"--disable-rpath" ,
104
87
]
105
- autotools .configure (args = conf_args , configure_dir = self ._source_subfolder )
106
- return autotools
107
-
108
- def build (self ):
109
- for patch in self .conan_data .get ("patches" , {}).get (self .version , []):
110
- tools .patch (** patch )
111
- if self .settings .compiler == "Visual Studio" :
88
+ if is_msvc (self ):
89
+ tc .extra_cflags .append ("-FS" )
90
+ tc .extra_cxxflags .append ("-FS" )
91
+ tc .generate ()
92
+
93
+ if is_msvc (self ):
94
+ env = Environment ()
95
+ dep_info = self .dependencies ["libiconv" ].cpp_info .aggregated_components ()
96
+ env .append ("CPPFLAGS" , [f"-I{ unix_path (self , p )} " for p in dep_info .includedirs ] + [f"-D{ d } " for d in dep_info .defines ])
97
+ env .append ("_LINK_" , [lib if lib .endswith (".lib" ) else f"{ lib } .lib" for lib in (dep_info .libs + dep_info .system_libs )])
98
+ env .append ("LDFLAGS" , [f"-L{ unix_path (self , p )} " for p in dep_info .libdirs ] + dep_info .sharedlinkflags + dep_info .exelinkflags )
99
+ env .append ("CFLAGS" , dep_info .cflags )
100
+ env .vars (self ).save_script ("conanautotoolsdeps_cl_workaround" )
101
+ else :
102
+ deps = AutotoolsDeps (self )
103
+ deps .generate ()
104
+
105
+ if is_msvc (self ):
106
+ env = Environment ()
107
+ automake_conf = self .dependencies .build ["automake" ].conf_info
108
+ compile_wrapper = unix_path (self , automake_conf .get ("user.automake:compile-wrapper" , check_type = str ))
109
+ ar_wrapper = unix_path (self , automake_conf .get ("user.automake:lib-wrapper" , check_type = str ))
110
+ # Workaround for iconv.lib not being found due to linker flag order
111
+ libiconv_libdir = unix_path (self , self .dependencies ["libiconv" ].cpp_info .aggregated_components ().libdir )
112
+ env .define ("CC" , f"{ compile_wrapper } cl -nologo -L{ libiconv_libdir } " )
113
+ env .define ("CXX" , f"{ compile_wrapper } cl -nologo" )
114
+ env .define ("LD" , "link -nologo" )
115
+ env .define ("AR" , f'{ ar_wrapper } lib' )
116
+ env .vars (self ).save_script ("conanbuild_msvc" )
117
+
118
+ def _patch_sources (self ):
119
+ apply_conandata_patches (self )
120
+ # Disable examples and tests
121
+ for subdir in ["examples" , "tests" , "fuzz" , "gltests" , os .path .join ("lib" , "gltests" ), "doc" ]:
122
+ save (self , os .path .join (self .source_folder , subdir , "Makefile.in" ), "all:\n install:\n " )
123
+
124
+ if is_msvc (self ):
112
125
if self .settings .arch in ("x86_64" , "armv8" , "armv8.3" ):
113
126
ssize = "signed long long int"
114
127
else :
115
128
ssize = "signed long int"
116
- tools .replace_in_file (os .path .join (self ._source_subfolder , "lib" , "stringprep.h" ),
117
- "ssize_t" , ssize )
118
- with self ._build_context ():
119
- autotools = self ._configure_autotools ()
120
- autotools .make (args = ["V=1" ])
129
+ replace_in_file (self , os .path .join (self .source_folder , "lib" , "stringprep.h" ), "ssize_t" , ssize )
121
130
122
- def package (self ):
123
- self .copy ("COPYING" , src = self ._source_subfolder , dst = "licenses" )
124
- with self ._build_context ():
125
- autotools = self ._configure_autotools ()
126
- autotools .install ()
131
+ if self .settings .os == "Windows" :
132
+ # Otherwise tries to create a symlink from GNUmakefile to itself, which fails on Windows
133
+ replace_in_file (self , os .path .join (self .source_folder , "configure" ),
134
+ '"$GNUmakefile") CONFIG_LINKS="$CONFIG_LINKS $GNUmakefile:$GNUmakefile" ;;' , "" )
135
+ replace_in_file (self , os .path .join (self .source_folder , "configure" ),
136
+ 'ac_config_links="$ac_config_links $GNUmakefile:$GNUmakefile"' , "" )
127
137
138
+ def build (self ):
139
+ self ._patch_sources ()
140
+ autotools = Autotools (self )
141
+ autotools .configure ()
142
+ autotools .make ()
143
+
144
+ def package (self ):
145
+ copy (self , "COPYING" , self .source_folder , os .path .join (self .package_folder , "licenses" ))
146
+ autotools = Autotools (self )
147
+ autotools .install ()
128
148
rmdir (self , os .path .join (self .package_folder , "lib" , "pkgconfig" ))
129
149
rmdir (self , os .path .join (self .package_folder , "share" ))
130
- tools .remove_files_by_mask (os .path .join (self .package_folder , "lib" ), "*.la" )
150
+ rm (self , "*.la" , os .path .join (self .package_folder , "lib" ), recursive = True )
151
+
152
+ if is_msvc (self ) and self .options .shared :
153
+ os .rename (os .path .join (self .package_folder , "lib" , "idn.dll.lib" ),
154
+ os .path .join (self .package_folder , "lib" , "idn-12.lib" ))
131
155
132
156
def package_info (self ):
133
- self .cpp_info .libs = ["idn" ]
134
- self .cpp_info .names ["pkg_config" ] = "libidn"
157
+ if is_msvc (self ) and self .options .shared :
158
+ self .cpp_info .libs = ["idn-12" ]
159
+ else :
160
+ self .cpp_info .libs = ["idn" ]
161
+ self .cpp_info .set_property ("pkg_config_name" , "libidn" )
135
162
if self .settings .os in ["Linux" , "FreeBSD" ]:
136
163
if self .options .threads :
137
164
self .cpp_info .system_libs = ["pthread" ]
138
165
if self .settings .os == "Windows" :
139
166
if not self .options .shared :
140
167
self .cpp_info .defines = ["LIBIDN_STATIC" ]
141
168
169
+ # TODO: to remove in conan v2
142
170
bin_path = os .path .join (self .package_folder , "bin" )
143
- self .output .info ("Appending PATH environment variable: {}" .format (bin_path ))
144
171
self .env_info .PATH .append (bin_path )
145
-
0 commit comments