You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apple M1 macOS Monterey下Rust编译Diesel+PostgreSQL遇-lpq库缺失错误

在Apple M1 macOS上Diesel+PostgreSQL编译失败的解决建议

问题概述

在Apple M1芯片的macOS Monterey系统中,使用Rust Diesel框架连接PostgreSQL时,编译阶段出现链接错误,提示找不到libpq库。

报错信息

= note: ld: library not found for -lpq clang: error: linker command failed with exit code 1 (use -v to see invocation)

已尝试操作

  • 执行brew install libpq安装libpq
  • 设置环境变量PQ_LIB_DIR="$(brew --prefix libpq)/lib"
  • 尝试过Stack Overflow上的相关解决方案,但问题未解决

相关代码文件

main.rs

use anyhow::Result;
use diesel::query_dsl::RunQueryDsl;
use diesel_orm::{
    establish_connection,
    models::{Event, User},
    schema::{events::dsl::events, users::dsl::users},
};

fn main() -> Result<()> {
    let connection = establish_connection();
    let event_results = events.load::<Event>(&connection)?;
    let user_results = users.load::<User>(&connection)?;

    println!("Displaying {} events", event_results.len());
    for event in event_results {
        println!("{}", event.name);
    }
    println!("Displaying {} users", user_results.len());
    for user in user_results {
        println!("{}", user.user_name);
    }
    Ok(())
}

lib.rs

#![warn(clippy::pedantic)]
#![allow(clippy::must_use_candidate)]
#[macro_use]
extern crate diesel;
use crate::models::{Event, NewEvent, NewUser, User};
use crate::schema::{events::dsl::events, users::dsl::users};
use anyhow::Result;
use diesel::pg::PgConnection;
use diesel::prelude::*;
use diesel::query_dsl::RunQueryDsl;
use dotenv::dotenv;
use std::env::var;

pub mod models;
pub mod schema;

/// # Panics
/// Function panics is the database connection fails
pub fn establish_connection() -> PgConnection {
    dotenv().ok();

    let database_url = var("DATABASE_URL").expect("DATABASE_URL must be set");
    PgConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error connecting to {database_url}"))
}

pub fn create_event(conn: &PgConnection, name: &str) -> Event {
    use schema::events;

    let new_event = NewEvent {
        name,
        ..Default::default()
    };

    diesel::insert_into(events::table)
        .values(&new_event)
        .get_result(conn)
        .expect("Error inserting new event")
}

pub fn create_user<'a>(conn: &PgConnection, user_name: &'a str, password: &'a str) -> User {
    use schema::users;

    let new_user = NewUser {
        user_name,
        password,
        liked_event_ids: &[],
        disliked_event_ids: &[],
    };

    diesel::insert_into(users::table)
        .values(&new_user)
        .get_result(conn)
        .expect("Error inserting new user")
}

/// Gets all events in database
///
/// # Errors
///
/// Returns [`Err`] if it is unable to retrieve `Event`s
pub fn get_events(conn: &PgConnection) -> Result<Vec<Event>> {
    Ok(events.load::<Event>(conn)?)
}

/// Gets all users in database
///
/// # Errors
///
/// Returns [`Err`] if it is unable to retrieve `User`s
pub fn get_users(conn: &PgConnection) -> Result<Vec<User>> {
    Ok(users.load::<User>(conn)?)
}

schema.rs

table! {
    events (id) {
        id -> Int4,
        name -> Text,
        uri -> Nullable<Text>,
        startdate -> Nullable<Text>,
        enddate -> Nullable<Text>,
        category -> Nullable<Text>,
        info -> Nullable<Text>,
        bookurl -> Nullable<Text>,
        price -> Nullable<Text>,
        location -> Nullable<Text>,
        source -> Nullable<Text>,
    }
}

table! {
    users (id) {
        id -> Int4,
        user_name -> Text,
        password -> Text,
        liked_event_ids -> Nullable<Array<Int4>>,
        disliked_event_ids -> Nullable<Array<Int4>>,
    }
}

allow_tables_to_appear_in_same_query!(
    events,
    users,
);

models.rs

use super::schema::{events, users};
use diesel::Queryable;
use serde::{Deserialize, Serialize};

#[derive(Debug, Queryable, Deserialize, Serialize)]
pub struct User {
    pub id: i32,
    pub user_name: String,
    pub password: String,
    pub likes: Option<Vec<i32>>,
    pub dislikes: Option<Vec<i32>>,
}

#[derive(Debug, Queryable, Deserialize, Serialize)]
pub struct Event {
    pub id: i32,
    pub name: String,
    pub uri: Option<String>,
    pub start_date: Option<String>,
    pub end_date: Option<String>,
    pub category: Option<String>,
    pub info: Option<String>,
    pub book_url: Option<String>,
    pub price: Option<String>,
    pub location: Option<String>,
    pub source: Option<String>,
}

#[derive(Insertable)]
#[table_name = "users"]
pub struct NewUser<'a> {
    pub user_name: &'a str,
    pub password: &'a str,
    pub liked_event_ids: &'a [i32],
    pub disliked_event_ids: &'a [i32],
}

#[derive(Default, Insertable)]
#[table_name = "events"]
pub struct NewEvent<'a> {
    pub name: &'a str,
    pub uri: Option<&'a str>,
    pub startdate: Option<&'a str>,
    pub enddate: Option<&'a str>,
    pub category: Option<&'a str>,
    pub info: Option<&'a str>,
    pub bookurl: Option<&'a str>,
    pub price: Option<&'a str>,
    pub location: Option<&'a str>,
    pub source: Option<&'a str>,
}

Cargo.toml

[package]
name = "diesel_orm"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
diesel = { version = "1.4.4", features = ["postgres"] }
dotenv = "0.15"
serde = { version = "1.0", features = ["derive"] }
anyhow = "1.0.13"

解决建议

1. 确保环境变量生效

在终端执行以下命令,临时加载libpq路径并重新编译:

export PQ_LIB_DIR=$(brew --prefix libpq)/lib
export PATH="$(brew --prefix libpq)/bin:$PATH"
cargo build

如果需要永久生效,将上述两行添加到shell配置文件:

  • zsh用户:编辑~/.zshrc,添加后执行source ~/.zshrc
  • bash用户:编辑~/.bash_profile,添加后执行source ~/.bash_profile

2. 给Cargo指定libpq链接路径

在项目根目录创建.cargo/config.toml文件,写入以下内容(适配M1芯片的brew路径):

[target.aarch64-apple-darwin]
rustflags = [
  "-L", "/opt/homebrew/opt/libpq/lib",
  "-l", "pq",
]

保存后重新运行cargo build。

3. 升级Diesel版本

当前使用的Diesel 1.4.4版本较旧,对M1芯片的支持可能不完善,建议升级到最新稳定版:
修改Cargo.toml中的Diesel依赖:

diesel = { version = "2.1.0", features = ["postgres"] }

升级后需注意API变化,例如establish_connection的调用方式可能需要调整,同时重新生成数据库schema(若使用diesel-cli)。

4. 正确安装diesel-cli(若使用)

如果需要用diesel-cli管理数据库,安装时需指定libpq路径:

PQ_LIB_DIR=$(brew --prefix libpq)/lib cargo install diesel_cli --no-default-features --features postgres

5. 验证libpq安装路径

执行以下命令确认libpq的安装路径是否正确:

brew --prefix libpq

M1芯片上正常输出应为/opt/homebrew/opt/libpq,再检查该路径下是否存在libpq库文件:

ls $(brew --prefix libpq)/lib/libpq.dylib

若文件不存在,重新执行brew reinstall libpq修复安装。

内容的提问来源于stack exchange,提问作者trp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 23:05:31