licode學習之編譯篇--3
上一篇中,提示找不到NICE庫,先看看CMakList裡面吧
[[email protected] erizo]# pwd /home/test/licode-master/erizo [[email protected] erizo]# vim src/CMakeLists.txt #global variable set(THIRD_PARTY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/../../build/libdeps/build/include/") set(THIRD_PARTY_LIB "${CMAKE_CURRENT_SOURCE_DIR}/../../build/libdeps/build/lib/") ## Depencencies # GLIB find_package(Glib REQUIRED) include_directories(${GLIB_INCLUDE_DIRS}) # BOOST set (BOOST_LIBS thread regex system) find_package(Boost COMPONENTS ${BOOST_LIBS} REQUIRED) # GTHREAD find_library(GTHREAD gthread-2.0 HINTS "${THIRD_PARTY_LIB}") test_lib(${GTHREAD}) # SRTP find_library(SRTP srtp2 HINTS"${THIRD_PARTY_LIB}") test_lib(${SRTP}) # NICE find_library(NICE nice HINTS "${THIRD_PARTY_LIB}") test_lib(${NICE})
看來"${CMAKE_CURRENT_SOURCE_DIR}/../../build/libdeps/build/lib/裡面沒有nice庫
進到目錄:
[[email protected] libdeps]# ls build libav-11.9 libnice-0.1.4 libnice-0.1.4.tar.gz libsrtp-2.1.0 libsrtp-2.1.0.tar.gz nvm openssl-1.0.2p openssl-1.0.2p.tar.gz opus-1.1.tar.gz v11.9.tar.gz [[email protected] libdeps]# pwd /home/test/licode-master/build/libdeps [[email protected] libdeps]# ls build/lib/ engines/ libcrypto.a libsrtp2.a libssl.a pkgconfig/
確實是沒有nice庫,但是nice已經下載了,只是沒有編譯,對nice進行編譯
[[email protected] libnice-0.1.4]# ls aclocal.m4 AUTHORS ChangeLog config.guess config.log configure COPYING COPYING.MPL docs gst INSTALL ltmain.sh Makefile.in NEWS random scripts stun TODO agent autogen.sh common.mk config.h.in config.sub configure.ac COPYING.LGPL depcomp examples gtk-doc.make install-sh Makefile.am missing nice README socket tests win32 [[email protected] libnice-0.1.4]# ./configure --prefix=/home/test/licode-master/build/libdeps/build/ threaded-example.c: In function ‘main’: threaded-example.c:110: warning: implicit declaration of function ‘g_thread_new’ threaded-example.c:110: warning: nested extern declaration of ‘g_thread_new’ threaded-example.c:110: warning: assignment makes pointer from integer without a cast threaded-example.c: At top level: threaded-example.c:53: error: storage size of ‘gather_mutex’ isn’t known threaded-example.c:53: error: storage size of ‘negotiate_mutex’ isn’t known threaded-example.c:54: error: storage size of ‘gather_cond’ isn’t known threaded-example.c:54: error: storage size of ‘negotiate_cond’ isn’t known
make錯誤,得先解決一下這個符號錯誤,看看53行
[[email protected] libnice-0.1.4]# vim examples/threaded-example.c
static GMutex gather_mutex, negotiate_mutex; static GCond gather_cond, negotiate_cond;
很簡單的定義程式碼,但是說不認識這個結構,令人費解了
看看GMutex定義,看看有沒有結構吧
[[email protected] libnice-0.1.4]# vim /usr/include/glib-2.0/glib/gthread.h typedef struct _GMutex GMutex; typedef struct _GCond GCond; typedef struct _GPrivate GPrivate; typedef struct _GStaticPrivate GStaticPrivate; typedef struct _GThreadFunctions GThreadFunctions; struct _GThreadFunctions { GMutex* (*mutex_new) (void); void (*mutex_lock) (GMutex *mutex); gboolean (*mutex_trylock) (GMutex *mutex); void (*mutex_unlock) (GMutex *mutex); void (*mutex_free) (GMutex *mutex); GCond* (*cond_new) (void); void (*cond_signal) (GCond *cond); void (*cond_broadcast) (GCond *cond); void (*cond_wait) (GCond *cond, GMutex *mutex); gboolean (*cond_timed_wait) (GCond *cond, GMutex *mutex, GTimeVal *end_time); void (*cond_free) (GCond *cond); GPrivate* (*private_new) (GDestroyNotify destructor); gpointer (*private_get) (GPrivate *private_key); void (*private_set) (GPrivate *private_key, gpointer data); void (*thread_create) (GThreadFunc func, gpointer data, gulong stack_size, gboolean joinable, gboolean bound, GThreadPriority priority, gpointer thread, GError **error); void (*thread_yield) (void); void (*thread_join) (gpointer thread); void (*thread_exit) (void); void (*thread_set_priority)(gpointer thread, GThreadPriority priority); void (*thread_self) (gpointer thread); gboolean (*thread_equal) (gpointer thread1, gpointer thread2); }; GLIB_VAR GThreadFunctions g_thread_functions_for_glib_use; GLIB_VAR gboolean g_thread_use_default_impl; GLIB_VAR gboolean g_threads_got_initialized;
看這個樣子,是這個版本的glib並不支援GMutex結構體,而改為函式呼叫,並且提供預設管理以及外部處理管理。
目前我們只需要讓example編譯通過,直接使用預設的即可。
將threaded_example.c修改為:
1 /* 2 * Copyright 2013 University of Chicago 3 * Contact: Bryce Allen 4 * Copyright 2013 Collabora Ltd. 5 * Contact: Youness Alaoui 6 * 7 * The contents of this file are subject to the Mozilla Public License Version 8 * 1.1 (the "License"); you may not use this file except in compliance with 9 * the License. You may obtain a copy of the License at 10 * http://www.mozilla.org/MPL/ 11 * 12 * Software distributed under the License is distributed on an "AS IS" basis, 13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 14 * for the specific language governing rights and limitations under the 15 * License. 16 * 17 * Alternatively, the contents of this file may be used under the terms of the 18 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which 19 * case the provisions of LGPL are applicable instead of those above. If you 20 * wish to allow use of your version of this file only under the terms of the 21 * LGPL and not to allow others to use your version of this file under the 22 * MPL, indicate your decision by deleting the provisions above and replace 23 * them with the notice and other provisions required by the LGPL. If you do 24 * not delete the provisions above, a recipient may use your version of this 25 * file under either the MPL or the LGPL. 26 */ 27 28 /* 29 * Example using libnice to negotiate a UDP connection between two clients, 30 * possibly on the same network or behind different NATs and/or stateful 31 * firewalls. 32 * 33 * Build: 34 * gcc -o threaded-example threaded-example.c `pkg-config --cflags --libs nice` 35 * 36 * Run two clients, one controlling and one controlled: 37 * threaded-example 0 $(host -4 -t A stun.stunprotocol.org | awk '{ print $4 }') 38 * threaded-example 1 $(host -4 -t A stun.stunprotocol.org | awk '{ print $4 }') 39 */ 40 #include <stdlib.h> 41 #include <stdio.h> 42 #include <string.h> 43 #include <ctype.h> 44 #include <unistd.h> 45 46 #include <agent.h> 47 48 static GMainLoop *gloop; 49 static gchar *stun_addr = NULL; 50 static guint stun_port; 51 static gboolean controlling; 52 static gboolean exit_thread, candidate_gathering_done, negotiation_done; 53 static GMutex* gather_mutex = NULL, *negotiate_mutex = NULL;//modify use pointer 54 static GCond* gather_cond = NULL, *negotiate_cond = NULL;//modify use pointer 55 56 static const gchar *candidate_type_name[] = {"host", "srflx", "prflx", "relay"}; 57 58 static const gchar *state_name[] = {"disconnected", "gathering", "connecting", 59 "connected", "ready", "failed"}; 60 61 static int print_local_data(NiceAgent *agent, guint stream_id, 62 guint component_id); 63 static int parse_remote_data(NiceAgent *agent, guint stream_id, 64 guint component_id, char *line); 65 static void cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, 66 gpointer data); 67 static void cb_new_selected_pair(NiceAgent *agent, guint stream_id, 68 guint component_id, gchar *lfoundation, 69 gchar *rfoundation, gpointer data); 70 static void cb_component_state_changed(NiceAgent *agent, guint stream_id, 71 guint component_id, guint state, 72 gpointer data); 73 static void cb_nice_recv(NiceAgent *agent, guint stream_id, guint component_id, 74 guint len, gchar *buf, gpointer data); 75 76 static void * example_thread(void *data); 77 78 int 79 main(int argc, char *argv[]) 80 { 81 82 gather_mutex = g_mutex_new(); 83 negotiate_mutex = g_mutex_new(); 84 gather_cond = g_cond_new(); 85 negotiate_cond = g_cond_new(); 86 GThread *gexamplethread; 87 88 // Parse arguments 89 if (argc > 4 || argc < 2 || argv[1][1] != '\0') { 90 fprintf(stderr, "Usage: %s 0|1 stun_addr [stun_port]\n", argv[0]); 91 return EXIT_FAILURE; 92 } 93 controlling = argv[1][0] - '0'; 94 if (controlling != 0 && controlling != 1) { 95 fprintf(stderr, "Usage: %s 0|1 stun_addr [stun_port]\n", argv[0]); 96 return EXIT_FAILURE; 97 } 98 99 if (argc > 2) { 100 stun_addr = argv[2]; 101 if (argc > 3) 102 stun_port = atoi(argv[3]); 103 else 104 stun_port = 3478; 105 106 g_debug("Using stun server '[%s]:%u'\n", stun_addr, stun_port); 107 } 108 109 g_type_init(); 110 111 gloop = g_main_loop_new(NULL, FALSE); 112 // Run the mainloop and the example thread 113 exit_thread = FALSE; 114 //gexamplethread = g_thread_new("example thread", &example_thread, NULL); 115 GError* ger = NULL; 116 gexamplethread=g_thread_create(&example_thread, NULL, 1, &ger); 117 g_main_loop_run (gloop); 118 exit_thread = TRUE; 119 120 g_thread_join (gexamplethread); 121 g_main_loop_unref(gloop); 122 123 return EXIT_SUCCESS; 124 } 125 126 static void * 127 example_thread(void *data) 128 { 129 NiceAgent *agent; 130 NiceCandidate *local, *remote; 131 GIOChannel* io_stdin; 132 guint stream_id; 133 gchar *line = NULL; 134 int rval; 135 136 io_stdin = g_io_channel_unix_new(fileno(stdin)); 137 g_io_channel_set_flags (io_stdin, G_IO_FLAG_NONBLOCK, NULL); 138 139 // Create the nice agent 140 agent = nice_agent_new(g_main_loop_get_context (gloop), 141 NICE_COMPATIBILITY_RFC5245); 142 if (agent == NULL) 143 g_error("Failed to create agent"); 144 145 // Set the STUN settings and controlling mode 146 if (stun_addr) { 147 g_object_set(G_OBJECT(agent), "stun-server", stun_addr, NULL); 148 g_object_set(G_OBJECT(agent), "stun-server-port", stun_port, NULL); 149 } 150 g_object_set(G_OBJECT(agent), "controlling-mode", controlling, NULL); 151 152 // Connect to the signals 153 g_signal_connect(G_OBJECT(agent), "candidate-gathering-done", 154 G_CALLBACK(cb_candidate_gathering_done), NULL); 155 g_signal_connect(G_OBJECT(agent), "new-selected-pair", 156 G_CALLBACK(cb_new_selected_pair), NULL); 157 g_signal_connect(G_OBJECT(agent), "component-state-changed", 158 G_CALLBACK(cb_component_state_changed), NULL); 159 160 // Create a new stream with one component 161 stream_id = nice_agent_add_stream(agent, 1); 162 if (stream_id == 0) 163 g_error("Failed to add stream"); 164 165 // Attach to the component to receive the data 166 // Without this call, candidates cannot be gathered 167 nice_agent_attach_recv(agent, stream_id, 1, 168 g_main_loop_get_context (gloop), cb_nice_recv, NULL); 169 170 // Start gathering local candidates 171 if (!nice_agent_gather_candidates(agent, stream_id)) 172 g_error("Failed to start candidate gathering"); 173 174 g_debug("waiting for candidate-gathering-done signal..."); 175 176 g_mutex_lock(gather_mutex); 177 while (!exit_thread && !candidate_gathering_done) 178 g_cond_wait(gather_cond, gather_mutex); 179 g_mutex_unlock(gather_mutex); 180 if (exit_thread) 181 goto end; 182 183 // Candidate gathering is done. Send our local candidates on stdout 184 printf("Copy this line to remote client:\n"); 185 printf("\n "); 186 print_local_data(agent, stream_id, 1); 187 printf("\n"); 188 189 // Listen on stdin for the remote candidate list 190 printf("Enter remote data (single line, no wrapping):\n"); 191 printf("> "); 192 fflush (stdout); 193 while (!exit_thread) { 194 GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL); 195 if (s == G_IO_STATUS_NORMAL) { 196 // Parse remote candidate list and set it on the agent 197 rval = parse_remote_data(agent, stream_id, 1, line); 198 if (rval == EXIT_SUCCESS) { 199 g_free (line); 200 break; 201 } else { 202 fprintf(stderr, "ERROR: failed to parse remote data\n"); 203 printf("Enter remote data (single line, no wrapping):\n"); 204 printf("> "); 205 fflush (stdout); 206 } 207 g_free (line); 208 } else if (s == G_IO_STATUS_AGAIN) { 209 usleep (100000); 210 } 211 } 212 g_debug("waiting for state READY or FAILED signal..."); 213 g_mutex_lock(negotiate_mutex); 214 while (!exit_thread && !negotiation_done) 215 g_cond_wait(negotiate_cond, negotiate_mutex); 216 g_mutex_unlock(negotiate_mutex); 217 if (exit_thread) 218 goto end; 219 220 // Get current selected candidate pair and print IP address used 221 if (nice_agent_get_selected_pair (agent, stream_id, 1, 222 &local, &remote)) { 223 gchar ipaddr[INET6_ADDRSTRLEN]; 224 225 nice_address_to_string(&local->addr, ipaddr); 226 printf("\nNegotiation complete: ([%s]:%d,", 227 ipaddr, nice_address_get_port(&local->addr)); 228 nice_address_to_string(&remote->addr, ipaddr); 229 printf(" [%s]:%d)\n", ipaddr, nice_address_get_port(&remote->addr)); 230 } 231 232 // Listen to stdin and send data written to it 233 printf("\nSend lines to remote (Ctrl-D to quit):\n"); 234 printf("> "); 235 fflush (stdout); 236 while (!exit_thread) { 237 GIOStatus s = g_io_channel_read_line (io_stdin, &line, NULL, NULL, NULL); 238 if (s == G_IO_STATUS_NORMAL) { 239 nice_agent_send(agent, stream_id, 1, strlen(line), line); 240 g_free (line); 241 printf("> "); 242 fflush (stdout); 243 } else if (s == G_IO_STATUS_AGAIN) { 244 usleep (100000); 245 } else { 246 // Ctrl-D was pressed. 247 nice_agent_send(agent, stream_id, 1, 1, "\0"); 248 break; 249 } 250 } 251 252 end: 253 g_io_channel_unref (io_stdin); 254 g_object_unref(agent); 255 g_main_loop_quit (gloop); 256 257 return NULL; 258 } 259 static void 260 cb_candidate_gathering_done(NiceAgent *agent, guint stream_id, 261 gpointer data) 262 { 263 g_debug("SIGNAL candidate gathering done\n"); 264 265 g_mutex_lock(gather_mutex); 266 candidate_gathering_done = TRUE; 267 g_cond_signal(gather_cond); 268 g_mutex_unlock(gather_mutex); 269 } 270 271 static void 272 cb_component_state_changed(NiceAgent *agent, guint stream_id, 273 guint component_id, guint state, 274 gpointer data) 275 { 276 g_debug("SIGNAL: state changed %d %d %s[%d]\n", 277 stream_id, component_id, state_name[state], state); 278 279 if (state == NICE_COMPONENT_STATE_READY) { 280 g_mutex_lock(negotiate_mutex); 281 negotiation_done = TRUE; 282 g_cond_signal(negotiate_cond); 283 g_mutex_unlock(negotiate_mutex); 284 } else if (state == NICE_COMPONENT_STATE_FAILED) { 285 g_main_loop_quit (gloop); 286 } 287 } 288 289 290 static void 291 cb_new_selected_pair(NiceAgent *agent, guint stream_id, 292 guint component_id, gchar *lfoundation, 293 gchar *rfoundation, gpointer data) 294 { 295 g_debug("SIGNAL: selected pair %s %s", lfoundation, rfoundation); 296 } 297 298 static void 299 cb_nice_recv(NiceAgent *agent, guint stream_id, guint component_id, 300 guint len, gchar *buf, gpointer data) 301 { 302 if (len == 1 && buf[0] == '\0') 303 g_main_loop_quit (gloop); 304 305 printf("%.*s", len, buf); 306 fflush(stdout); 307 } 308 static NiceCandidate * 309 parse_candidate(char *scand, guint stream_id) 310 { 311 NiceCandidate *cand = NULL; 312 NiceCandidateType ntype; 313 gchar **tokens = NULL; 314 guint i; 315 316 tokens = g_strsplit (scand, ",", 5); 317 for (i = 0; tokens && tokens[i]; i++); 318 if (i != 5) 319 goto end; 320 321 for (i = 0; i < G_N_ELEMENTS (candidate_type_name); i++) { 322 if (strcmp(tokens[4], candidate_type_name[i]) == 0) { 323 ntype = i; 324 break; 325 } 326 } 327 if (i == G_N_ELEMENTS (candidate_type_name)) 328 goto end; 329 330 cand = nice_candidate_new(ntype); 331 cand->component_id = 1; 332 cand->stream_id = stream_id; 333 cand->transport = NICE_CANDIDATE_TRANSPORT_UDP; 334 strncpy(cand->foundation, tokens[0], NICE_CANDIDATE_MAX_FOUNDATION); 335 cand->priority = atoi (tokens[1]); 336 337 if (!nice_address_set_from_string(&cand->addr, tokens[2])) { 338 g_message("failed to parse addr: %s", tokens[2]); 339 nice_candidate_free(cand); 340 cand = NULL; 341 goto end; 342 } 343 344 nice_address_set_port(&cand->addr, atoi (tokens[3])); 345 346 end: 347 g_strfreev(tokens); 348 349 return cand; 350 } 351 static int 352 print_local_data (NiceAgent *agent, guint stream_id, guint component_id) 353 { 354 int result = EXIT_FAILURE; 355 gchar *local_ufrag = NULL; 356 gchar *local_password = NULL; 357 gchar ipaddr[INET6_ADDRSTRLEN]; 358 GSList *cands = NULL, *item; 359 360 if (!nice_agent_get_local_credentials(agent, stream_id, 361 &local_ufrag, &local_password)) 362 goto end; 363 364 cands = nice_agent_get_local_candidates(agent, stream_id, component_id); 365 if (cands == NULL) 366 goto end; 367 368 printf("%s %s", local_ufrag, local_password); 369 370 for (item = cands; item; item = item->next) { 371 NiceCandidate *c = (NiceCandidate *)item->data; 372 373 nice_address_to_string(&c->addr, ipaddr); 374 375 // (foundation),(prio),(addr),(port),(type) 376 printf(" %s,%u,%s,%u,%s", 377 c->foundation, 378 c->priority, 379 ipaddr, 380 nice_address_get_port(&c->addr), 381 candidate_type_name[c->type]); 382 } 383 printf("\n"); 384 result = EXIT_SUCCESS; 385 386 end: 387 if (local_ufrag) 388 g_free(local_ufrag); 389 if (local_password) 390 g_free(local_password); 391 if (cands) 392 g_slist_free_full(cands, (GDestroyNotify)&nice_candidate_free); 393 394 return result; 395 } 396 static int 397 parse_remote_data(NiceAgent *agent, guint stream_id, 398 guint component_id, char *line) 399 { 400 GSList *remote_candidates = NULL; 401 gchar **line_argv = NULL; 402 const gchar *ufrag = NULL; 403 const gchar *passwd = NULL; 404 int result = EXIT_FAILURE; 405 int i; 406 407 line_argv = g_strsplit_set (line, " \t\n", 0); 408 for (i = 0; line_argv && line_argv[i]; i++) { 409 if (strlen (line_argv[i]) == 0) 410 continue; 411 412 // first two args are remote ufrag and password 413 if (!ufrag) { 414 ufrag = line_argv[i]; 415 } else if (!passwd) { 416 passwd = line_argv[i]; 417 } else { 418 // Remaining args are serialized canidates (at least one is required) 419 NiceCandidate *c = parse_candidate(line_argv[i], stream_id); 420 421 if (c == NULL) { 422 g_message("failed to parse candidate: %s", line_argv[i]); 423 goto end; 424 } 425 remote_candidates = g_slist_prepend(remote_candidates, c); 426 } 427 } 428 if (ufrag == NULL || passwd == NULL || remote_candidates == NULL) { 429 g_message("line must have at least ufrag, password, and one candidate"); 430 goto end; 431 } 432 433 if (!nice_agent_set_remote_credentials(agent, stream_id, ufrag, passwd)) { 434 g_message("failed to set remote credentials"); 435 goto end; 436 } 437 438 // Note: this will trigger the start of negotiation. 439 if (nice_agent_set_remote_candidates(agent, stream_id, component_id, 440 remote_candidates) < 1) { 441 g_message("failed to set remote candidates"); 442 goto end; 443 } 444 445 result = EXIT_SUCCESS; 446 447 end: 448 if (line_argv != NULL) 449 g_strfreev(line_argv); 450 if (remote_candidates != NULL) 451 g_slist_free_full(remote_candidates, (GDestroyNotify)&nice_candidate_free); 452 453 return result; 454 }
修改的主要部分為:不使用GMutex,GCond變數,改為指標,在main函式開始時進行初始化。
執行make,還有example錯誤,使用相同的方式進行修改
[[email protected] libnice-0.1.4]# make [[email protected] libnice-0.1.4]# make install [[email protected] libnice-0.1.4]# ls ../build/lib/ engines/ libcrypto.a libnice.a libnice.la libnice.so libnice.so.10 libnice.so.10.2.0 libsrtp2.a libssl.a pkgconfig/
nice庫已經編譯出來了。
接著進入c++程式碼編譯目錄
[[email protected] erizo]# ls build buildProject.sh cleanObjectFiles.sh cmake generateEclipseProject.sh generateProject.sh runTests.sh src utils [[email protected] erizo]# pwd /home/test/licode-master/erizo [[email protected] erizo]# ./generateProject.sh generating release -- Found glib-2.0: /usr/include/glib-2.0, /usr/lib64/libglib-2.0.so;/usr/lib64/libgobject-2.0.so;/usr/lib64/libgthread-2.0.so -- Boost version: 1.41.0 -- Found the following Boost libraries: -- thread -- regex -- system CMake Error at CMakeLists.txt:7 (message): lib not found: AVUTIL-NOTFOUND check README Call Stack (most recent call first): CMakeLists.txt:91 (test_lib) -- Configuring incomplete, errors occurred!
現在已經不再報找不到nice庫錯誤了,但是報找AVUTIL庫錯誤,這個庫是ffmpeg的基本庫。
在licode的準備指令碼中,並沒有ffmpeg的相關下載,需要自己手動下載並且編譯ffmpeg
[[email protected] scripts]# git clone https://github.com/FFmpeg/FFmpeg.git /home/test/licode-master/build/libdeps/ffmpeg
[[email protected] ffmpeg]# ./configure --prefix=/home/test/licode-master/build/libdeps/build/ --disable-static --enable-shared
[[email protected] ffmpeg]# make
[[email protected] ffmpeg]# make install
[[email protected] erizo]# pwd /home/test/licode-master/erizo [[email protected] erizo]# ./generateProject.sh generating release -- Found glib-2.0: /usr/include/glib-2.0, /usr/lib64/libglib-2.0.so;/usr/lib64/libgobject-2.0.so;/usr/lib64/libgthread-2.0.so -- Boost version: 1.41.0 -- Found the following Boost libraries: -- thread -- regex -- system CMake Error at CMakeLists.txt:7 (message): lib not found: LOG-NOTFOUND check README Call Stack (most recent call first): CMakeLists.txt:102 (test_lib)
ffmpeg的庫已經都OK了,現在報找不到log庫
[[email protected] erizo]# vim src/CMakeLists.txt # LOG4CXX find_library(LOG log4cxx) test_lib(${LOG})
log指的是log4cxx
[[email protected] erizo]# yum install log4cxx Loaded plugins: fastestmirror, refresh-packagekit, security Setting up Install Process Loading mirror speeds from cached hostfile * base: mirrors.huaweicloud.com * epel: mirrors.aliyun.com * extras: mirrors.huaweicloud.com * remi-safe: mirror.innosol.asia * updates: mirror.bit.edu.cn No package log4cxx available. Error: Nothing to do
好吧,log4cxx在這個版本的centos上面,沒有提供,只能下載原始碼進行編譯了
apr: http://apr.apache.org/download.cgi
apr-util: http://apr.apache.org/download.cgi
log4cxx: http://logging.apache.org/log4cxx/download.html
下載軟體包,之後進行安裝
[[email protected] apr-1.6.5]# yum install libtool [[email protected] apr-1.6.5]# pwd /home/test/log4cxx/apr-1.6.5 [[email protected] apr-1.6.5]# ./configure --prefix=/usr --libdir=/usr/lib64 --bindir=/usr/bin [[email protected] apr-1.6.5]# make [[email protected] apr-1.6.5]# make install [[email protected] apr-1.6.5]# cd .. [[email protected] log4cxx]# tar vxf apr-util-1.6.1.tar.gz [[email protected] log4cxx]# cd apr-util-1.6.1 [[email protected] apr-util-1.6.1]# ./configure --prefix=/usr --bindir=/usr/bin --libdir=/usr/lib64 --with-apr=/usr [[email protected] apr-util-1.6.1]# make [[email protected] apr-util-1.6.1]# make install [[email protected] apr-util-1.6.1]# cd .. [[email protected] log4cxx]# tar vxf apache-log4cxx-0.10.0.tar.gz [[email protected] log4cxx]# cd apache-log4cxx-0.10.0 [[email protected] apache-log4cxx-0.10.0]# ./configure --prefix=/usr --bindir=/usr/bin --libdir=/usr/lib64 [[email protected] apache-log4cxx-0.10.0]# make inputstreamreader.cpp:66: error: 'memmove' was not declared in this scope make[3]: *** [inputstreamreader.lo] Error 1 make[3]: Leaving directory `/home/test/log4cxx/apache-log4cxx-0.10.0/src/main/cpp' make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory `/home/test/log4cxx/apache-log4cxx-0.10.0/src/main' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/test/log4cxx/apache-log4cxx-0.10.0/src' make: *** [all-recursive] Error 1 [[email protected] apache-log4cxx-0.10.0]# vim src/main/cpp/inputstreamreader.cpp #include <log4cxx/logstring.h> #include <log4cxx/helpers/inputstreamreader.h> #include <log4cxx/helpers/exception.h> #include <log4cxx/helpers/pool.h> #include <log4cxx/helpers/bytebuffer.h> #include <string.h>//add this line [[email protected] apache-log4cxx-0.10.0]# make socketoutputstream.cpp: In member function 'virtual void log4cxx::helpers::SocketOutputStream::write(log4cxx::helpers::ByteBuffer&, log4cxx::helpers::Pool&)': socketoutputstream.cpp:52: error: 'memcpy' was not declared in this scope [[email protected] apache-log4cxx-0.10.0]# vim src/main/cpp/socketoutputstream.cpp #include <log4cxx/logstring.h> #include <log4cxx/helpers/socketoutputstream.h> #include <log4cxx/helpers/socket.h> #include <log4cxx/helpers/bytebuffer.h> #include <string.h>//add this line [[email protected] apache-log4cxx-0.10.0]# make console.cpp: In function ‘int main(int, char**)’: console.cpp:58: error: ‘puts’ was not declared in this scope console.cpp:63: error: ‘strcmp’ was not declared in this scope console.cpp:66: error: ‘stderr’ was not declared in this scope console.cpp:66: error: ‘stdout’ was not declared in this scope console.cpp:66: error: ‘fputs’ was not declared in this scope console.cpp:69: error: ‘stderr’ was not declared in this scope console.cpp:69: error: ‘stdout’ was not declared in this scope console.cpp:102: error: ‘stderr’ was not declared in this scope console.cpp:102: error: ‘stdout’ was not declared in this scope console.cpp:104: error: ‘stderr’ was not declared in this scope console.cpp:104: error: ‘stdout’ was not declared in this scope console.cpp:107: error: ‘stderr’ was not declared in this scope console.cpp:107: error: ‘fputs’ was not declared in this scope console.cpp:110: error: ‘fflush’ was not declared in this scope [[email protected] apache-log4cxx-0.10.0]# vim src/examples/cpp/console.cpp #include <stdlib.h> #include <log4cxx/logger.h> #include <log4cxx/consoleappender.h> #include <log4cxx/simplelayout.h> #include <log4cxx/logmanager.h> #include <iostream> #include <locale.h> #include <string.h>//add this line #include <stdio.h>//add this line [[email protected] apache-log4cxx-0.10.0]# make install
log4cxx安裝成功
[[email protected] erizo]# pwd /home/test/licode-master/erizo [[email protected] erizo]# ./generateProject.sh
執行成功,之後就需要編譯了
[[email protected] erizo]# ./buildProject.sh /home/test/licode-master/erizo/build/debug/libdeps/nicer/src/project_nicer/src/net/transport_addr.c:478: error: ‘for’ loop initial declarations are only allowed in C99 mode [[email protected] erizo]# vim build/debug/libdeps/nicer/src/project_nicer/src/net/transport_addr.c int nr_transport_addr_get_private_addr_range(nr_transport_addr *addr) { switch(addr->ip_version){ case NR_IPV4: { UINT4 ip = ntohl(addr->u.addr4.sin_addr.s_addr); int i = 0; for (i=0; i<(sizeof(nr_private_ipv4_addrs)/sizeof(nr_transport_addr_mask)); i++) { if ((ip & nr_private_ipv4_addrs[i].mask) == nr_private_ipv4_addrs[i].addr) return i + 1; } } break; case NR_IPV6: return(0); default: UNIMPLEMENTED; } return(0); } [[email protected] erizo]# ./buildProject.sh /home/test/licode-master/erizo/build/debug/libdeps/nicer/src/project_nicer/src/stun/stun_util.c:97: error: ‘for’ loop initial declarations are only allowed in C99 mode [[email protected] erizo]# vim build/debug/libdeps/nicer/src/project_nicer/src/stun/stun_util.c int nr_stun_xor_mapped_address(UINT4 magicCookie, UINT12 transactionId, nr_transport_addr *from, nr_transport_addr *to) { int _status; switch (from->ip_version) { case NR_IPV4: nr_ip4_port_to_transport_addr( (ntohl(from->u.addr4.sin_addr.s_addr) ^ magicCookie), (ntohs(from->u.addr4.sin_port) ^ (magicCookie>>16)), from->protocol, to); break; case NR_IPV6: { int i = 0; union { unsigned char addr[16]; UINT4 addr32[4]; } maskedAddr; maskedAddr.addr32[0] = htonl(magicCookie); /* Passed in host byte order */ memcpy(&maskedAddr.addr32[1], transactionId.octet, sizeof(transactionId)); /* We now have the mask in network byte order */ /* Xor the address in network byte order */ for (i = 0; i < sizeof(maskedAddr); ++i) { maskedAddr.addr[i] ^= from->u.addr6.sin6_addr.s6_addr[i]; } [[email protected] erizo]# ./buildProject.sh cc1plus: error: unrecognized command line option "-std=c++11"
天啊,這可真是一個大問題了,竟然遇到了gcc版本過低的問題,看來得先考慮升級gcc的版本了
https://ftp.gnu.org/gnu/gcc/ 在裡面下載版本下載gcc4.8.5,當然下載其他的也可以
[[email protected] gcc-4.8.5]# pwd /home/test/log4cxx/gcc-4.8.5 [[email protected] gcc-4.8.5]# yum install gmp-devel [[email protected] gcc-4.8.5]# yum install mpfr-devel [[email protected] gcc-4.8.5]# yum install libmpc-devel [[email protected] gcc-4.8.5]# ./configure [[email protected] gcc-4.8.5]# make In file included from /usr/include/features.h:385:0, from /usr/include/stdio.h:28, from ../../.././libgcc/../gcc/tsystem.h:87, from ../../.././libgcc/libgcc2.c:27: /usr/include/gnu/stubs.h:7:27: fatal error: gnu/stubs-32.h: No such file or directory # include <gnu/stubs-32.h>
看來gcc的編譯裡面還有些事兒,下一篇再繼續吧