vs2019 - warning LNK4098 : 默认库“msvcrt.lib”与其他库的使用冲突

文章目录

    • vs2019 - warning LNK4098 : 默认库“msvcrt.lib”与其他库的使用冲突
    • 概述
    • 笔记
    • 实验 - 编译静态库
    • 实验 - 编译主工程,包含静态库
    • 实验主工程和静态库编译设置不同时的编译报错和警告
    • 备注
    • 备注 - 判断/Mdd, /Md
    • END

vs2019 - warning LNK4098 : 默认库“msvcrt.lib”与其他库的使用冲突

概述

在工程中看到了编译警告

warning LNK4098 : 默认库“msvcrt.lib”与其他库的使用冲突;请使用 / NODEFAULTLIB : library

今天想起来,验证一下问题原因。
做了实验,应该就是主工程包含了编译选项不同的静态库引起的。
e.g. DebugX64的主工程包含了ReleaseX64的静态库。
e.g. 主工程的运行时库是/Mdd, 静态库的运行时库为/Md

根据情况,如果忽略编译提示的库,也许能编译过(e.g. debugx64Mdd的主工程包含了ReleaseX64Md的静态库),但是可能有其他问题。
如果不是实在没招的情况,还是不要在编译器设置中忽略指定库。
在这里插入图片描述

笔记

实验 - 编译静态库

//! \file StaticLIbA.h

#ifndef __STATIC_LIB_A_H__
#define __STATIC_LIB_A_H__

bool isStaticLibAOnDebugBuild();


#endif // #ifndef __STATIC_LIB_A_H__

// StaticLibA.cpp : 定义静态库的函数。
//

#include "pch.h"
#include "framework.h"

bool isStaticLibAOnDebugBuild()
{
	bool b_rc = false;

	do {
#ifndef _DEBUG
		break;
#endif // !_DEBUG

		b_rc = true;
	} while (false);

	return b_rc;
}

将工程分别编译出debug_x64/release_x64的2个版本。
输出分别为 StaticLibA_release_x64_md.lib,StaticLibA_debug_x64_mdd.lib

实验 - 编译主工程,包含静态库

随便建立一个工程(e.g. vs2019 mfc dlg)


#include "StaticLIbA.h"


// warning LNK4098 : 默认库“msvcrt.lib”与其他库的使用冲突;请使用 / NODEFAULTLIB : library
// 如果编译时,出现了以上警告,要去检查主工程和静态库的编译设置是否相同,才是治本的方法。而不能按照编译提示去忽略msvcrt.lib
// 如果要治标,虽然能编译过,可能在运行时还会有其他问题。

// 如果静态库不是一个编译器搞出来的,有可能编译设置不一样,但是不太好整成一样。
// 这时,还是封装一个DLL, 将静态库封住,让DLL的设置和静态库的编译设置一样,这样好点。
// 让主工程调用DLL, 而不是直接包含静态库。

#if (defined(_DEBUG) && defined(_WIN64))
#pragma comment(lib, "StaticLibA_debug_x64_mdd.lib")

// #pragma comment(lib, "StaticLibA_release_x64_md.lib")
// 如果debug/x64的主工程包了 release_x64的静态库,虽然能编译过,但是有警告
// 如果此时按照编译提示去忽略 msvcrtd.lib, 虽然能编译过,但是只是治标,可能程序运行时还是其他问题。
// 
//1 > StaticLibA_release_x64_md.lib(StaticLibA.obj) : 找到 MSIL.netmodule 或使用 / GL 编译的模块;正在使用 / LTCG 重新启动链接;将 / LTCG 添加到链接命令行以改进链接器性能
//1 > LINK : warning LNK4075 : 忽略“ / INCREMENTAL”(由于“ / LTCG”规范)
//1 > msvcrtd.lib(initializers.obj) : warning LNK4098 : 默认库“msvcrt.lib”与其他库的使用冲突;请使用 / NODEFAULTLIB : library
#elif (defined(NDEBUG) && defined(_WIN64))
#pragma comment(lib, "StaticLibA_release_x64_md.lib")

// 如果 release_x64的主工程包了 debug_x64的静态库,就会编译不过报错。
// 如果此时按照编译提示去忽略 msvcrtd.lib, 虽然能编译过,但是只是治标,可能程序运行时还是其他问题。

// #pragma comment(lib, "StaticLibA_debug_x64_mdd.lib")
//1 > StaticLibA_debug_x64_mdd.lib(StaticLibA.obj) : warning LNK4075 : 忽略“ / EDITANDCONTINUE”(由于“ / OPT:ICF”规范)
//1 > msvcrt.lib(initializers.obj) : warning LNK4098 : 默认库“msvcrtd.lib”与其他库的使用冲突;请使用 / NODEFAULTLIB : library
//1 > msvcrtd.lib(init.obj) : error LNK2001 : 无法解析的外部符号 _CrtDbgReport
//1 > msvcrtd.lib(init.obj) : error LNK2001 : 无法解析的外部符号 _CrtDbgReportW

#endif

在主工程中用上静态库中的函数接口

void Cexp008TestTraceDlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码

	// TRACE 在debug模式下,会在VS2019的输出窗口打印信息
	// TRACE 在release模式下,不会在VS2019的输出窗口中打印信息
	TRACE(TEXT("this is a TRACE\n"));

	// 静态库 x86/x64, debug/release要和主工程一样
	// 静态库的工程属性页 => 配置属性 => c/c++ => 代码生成 => 运行库 => 要和主工程一样 e.g. 都是 /MD, 否则编译报错。
	if (isStaticLibAOnDebugBuild())
	{
		TRACE(TEXT("true == isStaticLibAOnDebugBuild()\n"));
		// 这里的TRACE在release版下打印不出来,这是对的。

		// 但是因为静态库是debug版的, 所以isStaticLibAOnDebugBuild()返回true
		AfxMessageBox(TEXT("true == isStaticLibAOnDebugBuild()")); // 可以执行messagebox
	}

#ifdef _DEBUG
	// 这里执行不到,因为主工程是release版的
	AfxMessageBox(TEXT("_DEBUG was defined"));
#endif // #ifdef _DEBUG

	/*
	release版的主工程包含debug版的静态库,虽然能编译过,但是有以下不正常的提示
	1>StaticLibA.lib(StaticLibA.obj) : warning LNK4075: 忽略“/EDITANDCONTINUE”(由于“/OPT:ICF”规范)
	1>正在生成代码
	1>Previous IPDB not found, fall back to full compilation.
	1>All 191 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
	*/

	CDialogEx::OnOK();
}

实验主工程和静态库编译设置不同时的编译报错和警告

通过实验,可以看出:

  • 只要主工程和静态库的编译设置一样(x86/x64 + debug/release + 运行时库(/Mdd,/Md))相同,就不会有任何警告,顺利编译完成,0警告,0错误。
  • 如果主工程和静态库的编译设置不同,会有非警告信息(也说明主工程和静态库不匹配),警告信息,编译错误信息。
    这时,如果不是真的没招(是第三方的静态库,自己编译不了),就不要去编译器中忽略特定库,而是要重新编译静态库,使主工程能包含匹配的静态库来解决编译警告/错误问题。

备注

我自己工程中也有这个警告,经过上面的实验,找了一下,确实包含了一个自己的静态库。静态库就编译了一个版本,在不同编译设置的主工程下,就是会有警告和错误。等下一步去将静态库编译成不同的版本来配合主工程来用。

如果调用的是DLL的接口,就不会有warning LNK4098 : 默认库的警告或错误,因为DLL的.lib中,只是接口的调用代理的代码(和我们自己loadlibray + getaddress一样),没其他的。

备注 - 判断/Mdd, /Md

如果为了更精确的让主工程包含匹配的静态库,除了 debug/release + x86/x64外,还要判断工程的运行时库。
MS官方有文档 https://learn.microsoft.com/zh-cn/cpp/build/reference/md-mt-ld-use-run-time-library?view=msvc-170

在这里插入图片描述

END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/578701.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[SWPUCTF-2022-新生赛]ez_sql

title:[SWPUCTF 2022 新生赛]ez_sql 审题 根据提示,POST传参 得到假的flag 判断类型 字符型注入 判断列数 发现空格和’or’被过滤 重新构造 nss-1/**/oorrder/**/by/**/4#发现为3个字段 采用联合注入union 爆库 发现union被过滤,双写union绕过 发…

以生命健康为中心的物联网旅居养老运营平台

随着科技的飞速发展和人口老龄化的日益加剧,养老问题逐渐成为社会关注的焦点。传统的养老模式已经难以满足现代老年人的多元化需求,因此,构建一个以生命健康为中心的物联网旅居养老运营平台显得尤为重要。 以生命健康为中心的物联网旅居养老运…

两大成果发布!“大规模量子云算力集群”和高性能芯片展示中国科技潜力

在当前的科技领域,量子计算的进步正日益引起全球的关注。中国在这一领域的进展尤为显著,今天,北京量子信息科学研究院(以下简称北京量子院)和中国科学院量子信息与量子科技创新研究院(以下简称量子创新院&a…

【c++】深入剖析与动手实践:C++中Stack与Queue的艺术

🔥个人主页:Quitecoder 🔥专栏:c笔记仓 朋友们大家好,本篇文章我们来到STL新的内容,stack和queue 目录 1. stack的介绍与使用函数介绍例题一:最小栈例题二:栈的压入、弹出队列栈的模…

Docker 的数据管理 与 Docker 镜像的创建

目录 一、Docker 的数据管理 1.1.数据卷 1.2.数据卷容器 1.3.容器互联(使用centos镜像) 二、Docker 镜像的创建 2.1.基于现有镜像创建 2.2.基于本地模板创建 2.3.基于Dockerfile创建 2.3.1联合文件系统(UnionFs) 2.3.2…

GDPU 竞赛技能实践 天码行空9

1. 埃式筛法 求区间[2, n]内所有的素数对 💖 Main.java import java.util.Scanner;public class Main {static int N (int) 1e8, cnt 0;static int[] p new int[N];static boolean[] st new boolean[N];public static void main(String[] args){Scanner sc …

使用grasshopper修改梁的起始点方向

一般北方向朝上的情况,梁的方向从南向北,从西向东。 现在使用grasshopper来判断起始点坐标,分辨是否错误。 交换起始点这个,我实在不会用电池操作,只好敲python代码实现了。代码如下: 如果会敲代码的同学…

66.网络游戏逆向分析与漏洞攻防-利用数据包构建角色信息-重新规划游戏分析信息的输出

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 如果看不懂、不知道现在做的什么,那就跟着做完看效果,代码看不懂是正常的,只要会抄就行,抄着抄着就能懂了 内容…

Apache Seata的可观测实践

title: Seata的可观测实践 keywords: [Seata、分布式事务、数据一致性、微服务、可观测] description: 本文介绍Seata在可观测领域的探索和实践 author: 刘戎-Seata 本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 Seata简介 Seata的…

STM32单片机通过ST-Link 烧录和调试

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 1. ST-LINK V2 ST LINK v2下载器用于STM32单片机,可以下载程序、调试程序、读取芯片数据,解除芯片读写保护等等,辅助软件用的是STM32 ST-LINK Utility。 STM32 ST-LINK Utility…

电脑上的任务管理器不见了?如何把它打开?

前言 今天小白在睡觉的时候突然梦见回到了学校的电脑教室…… 相信大家都会有体验:每次上电脑课的时候,老师都会通过某些软件监控和控制学生的电脑。 想退出被控端的软件?没机会!毕竟任务管理器也被禁用了,想整活都…

算法学习之单调栈

发射站 题目描述 某地有 N N N 个能量发射站排成一行,每个发射站 i i i 都有不相同的高度 H i H_i Hi​,并能向两边(两端的发射站只能向一边)同时发射能量值为 V i V_i Vi​ 的能量,发出的能量只被两边最近的且比…

Opencv_14_多边形填充与绘制

绘制多边形: 1)coInvert.polyline_drawing(src); 2)void ColorInvert::polyline_drawing(Mat& image) { Mat canvas Mat::zeros(Size(512, 512), CV_8UC3); Point p1(100, 100); Point p2(150, 100); Point p3(200…

TR6 - Transformer实战 单词预测

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目录 理论知识关于数据集 Wikitext-2 模型结构代码实现0. 环境1. 加载数据集2. 模型搭建3. 创建模型4. 单轮训练和评估的流程5. 训练 模型效果总结与心得体会 …

Openharmony - 设备异常关机Power Down问题分析

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 1.问题描述1.1出现power down的原因1.1.1硬件故障或信号1.1.2软件错误或系统崩溃2.抓日志信息2.1.抓日志方法2.2.问题初步分析3.问题排…

React复习笔记

基础语法 创建项目 借助脚手架,新建一个React项目(可以使用vite或者cra,这里使用cra) npx create-react-app 项目名 create-react-app是React脚手架的名称 启动项目 npm start 或者 yarn start src是源文件index.js相当于Vue的main.js文件。整个…

OC类与对象

OC类与对象 本篇是对上一篇的内容的继续学习。从单例模式开始继续学习 文章目录 单例模式定义应用场景特点单例模式的创建 隐藏与封装理解什么是封装目的访问控制符合成存取方法特性的指示符点语法访问属性 对象初始化便利的初始化方法 类的继承特点语法格式重写父类方法super关…

SimpleDateFormat类.Java

目录 1.1构造方法 1.2格式规则 1.3常用方法 1.4练习1( 出生日期) 1.5练习2(秒杀活动) java.text.SimpleDateFormat 是日期/时间格式化类,我们通过这个类可以帮我们完成日期和文本之间的转换,也就是可以在Date对象与String对象之间进行来…

机器学习理论基础—集成学习(1)

机器学习理论基础—集成学习 个体与集成 集成学习通过构建并结合多个学习器来完成学习任务,有时也称为多分类系统等。 分类: 根据集成学习中的个体学习器的不同可以分为同质集成(集成的学习器相同例如全部是决策树)&#xff0c…

上市公司专利数据、专利申请、专利授权和质量指标计算面板数据(1990-2022年)

01、数据简介 专利作为企业创新能力和核心竞争力的体现,越来越受到上市公司的重视。了解上市公司的专利数据、专利申请、专利授权和质量指标计算,有助于投资者更好地评估公司的创新能力和长期发展潜力。 通过分析上市公司的专利数据、专利申请、专利授…