@@ -38,6 +38,109 @@ def get_openmp_flags():
3838 return [], []
3939
4040
41+ import subprocess
42+
43+
44+ def ensure_cmake_build ():
45+ """确保CMake项目已构建,包括第三方库"""
46+ build_dir = os .path .join (PROJECT_ROOT , "build" )
47+
48+ try :
49+ # 检查build目录是否存在
50+ if not os .path .exists (build_dir ):
51+ print ("Creating build directory..." )
52+ os .makedirs (build_dir )
53+
54+ # 检查CMakeCache.txt是否存在,如果不存在则需要配置
55+ cmake_cache = os .path .join (build_dir , "CMakeCache.txt" )
56+ if not os .path .exists (cmake_cache ):
57+ print ("Configuring CMake..." )
58+ subprocess .run ([
59+ "cmake" ,
60+ "-DCMAKE_BUILD_TYPE=Release" ,
61+ "-DBUILD_TESTS=OFF" ,
62+ "-DCMAKE_POSITION_INDEPENDENT_CODE=ON" ,
63+ ".."
64+ ], cwd = build_dir , check = True )
65+
66+ # 检查第三方库是否已编译
67+ spdlog_lib = os .path .join (build_dir , "_deps" , "spdlog-build" , "libspdlog.a" )
68+ fmt_lib = os .path .join (build_dir , "_deps" , "fmt-build" , "libfmt.a" )
69+
70+ if not os .path .exists (spdlog_lib ) or not os .path .exists (fmt_lib ):
71+ print ("Building third-party libraries..." )
72+ # 先构建第三方库
73+ subprocess .run (["make" , "spdlog" , "fmt" , "-j$(nproc)" ], cwd = build_dir , check = True )
74+
75+ print ("CMake build setup completed." )
76+ return True
77+
78+ except subprocess .CalledProcessError as e :
79+ print (f"Error during CMake build: { e } " )
80+ return False
81+ except Exception as e :
82+ print (f"Unexpected error: { e } " )
83+ return False
84+
85+
86+ def get_cmake_target_info ():
87+ """获取CMake构建的第三方库信息"""
88+ # 首先确保CMake项目已构建
89+ if not ensure_cmake_build ():
90+ print ("Warning: CMake build failed, falling back to system libraries" )
91+ return [], [], [], []
92+
93+ try :
94+ build_dir = os .path .join (PROJECT_ROOT , "build" )
95+ deps_dir = os .path .join (build_dir , "_deps" )
96+
97+ include_dirs = []
98+ library_dirs = []
99+ libraries = []
100+ extra_objects = [] # 用于静态库
101+
102+ # spdlog路径
103+ spdlog_src = os .path .join (deps_dir , "spdlog-src" , "include" )
104+ spdlog_build = os .path .join (deps_dir , "spdlog-build" )
105+
106+ if os .path .exists (spdlog_src ):
107+ include_dirs .append (spdlog_src )
108+
109+ # 查找spdlog静态库
110+ spdlog_lib = os .path .join (spdlog_build , "libspdlog.a" )
111+ if os .path .exists (spdlog_lib ):
112+ extra_objects .append (spdlog_lib )
113+ print (f"Found spdlog library: { spdlog_lib } " )
114+ else :
115+ # 如果没有找到静态库,尝试动态库
116+ if os .path .exists (spdlog_build ):
117+ library_dirs .append (spdlog_build )
118+ libraries .append ("spdlog" )
119+
120+ # fmt路径
121+ fmt_src = os .path .join (deps_dir , "fmt-src" , "include" )
122+ fmt_build = os .path .join (deps_dir , "fmt-build" )
123+
124+ if os .path .exists (fmt_src ):
125+ include_dirs .append (fmt_src )
126+
127+ # 查找fmt静态库
128+ fmt_lib = os .path .join (fmt_build , "libfmt.a" )
129+ if os .path .exists (fmt_lib ):
130+ extra_objects .append (fmt_lib )
131+ print (f"Found fmt library: { fmt_lib } " )
132+ else :
133+ if os .path .exists (fmt_build ):
134+ library_dirs .append (fmt_build )
135+ libraries .append ("fmt" )
136+
137+ return include_dirs , library_dirs , libraries , extra_objects
138+
139+ except Exception as e :
140+ print (f"Warning: Could not get CMake target info: { e } " )
141+ return [], [], [], []
142+
143+
41144class BuildExt (build_ext ):
42145 user_options = build_ext .user_options + [('disable-openmp' , None , "Disable OpenMP support" )]
43146
@@ -58,13 +161,32 @@ def finalize_options(self):
58161 def build_extensions (self ):
59162 cpp_flag = '/std:c++17' if IS_WINDOWS else '-std=c++17'
60163
164+ # 获取CMake构建的第三方库信息
165+ cmake_includes , cmake_lib_dirs , cmake_libs , extra_objects = get_cmake_target_info ()
166+
61167 for ext in self .extensions :
62168 ext .extra_compile_args = [cpp_flag ]
63169 ext .include_dirs .extend ([
64170 pybind11 .get_include (),
65171 np .get_include (),
66172 SRC_DIR
67173 ])
174+
175+ # 添加CMake构建的第三方库
176+ ext .include_dirs .extend (cmake_includes )
177+ ext .library_dirs .extend (cmake_lib_dirs )
178+ ext .libraries .extend (cmake_libs )
179+
180+ # 添加静态库对象文件
181+ if extra_objects :
182+ if not hasattr (ext , 'extra_objects' ):
183+ ext .extra_objects = []
184+ ext .extra_objects .extend (extra_objects )
185+
186+ # 添加运行时库路径(仅对动态库)
187+ if cmake_lib_dirs :
188+ for lib_dir in cmake_lib_dirs :
189+ ext .extra_link_args .append (f'-Wl,-rpath,{ lib_dir } ' )
68190 if not IS_WINDOWS :
69191 ext .extra_compile_args += [
70192 f'-DVERSION_INFO="{ self .distribution .get_version ()} "' ,
0 commit comments